-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathtcp_socket.cr
100 lines (86 loc) · 2.75 KB
/
tcp_socket.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
require "./ip_socket"
# A Transmission Control Protocol (TCP/IP) socket.
#
# Usage example:
# ```
# require "socket"
#
# client = TCPSocket.new("localhost", 1234)
# client << "message\n"
# response = client.gets
# client.close
# ```
class TCPSocket < IPSocket
# Creates a new `TCPSocket`, waiting to be connected.
def self.new(family : Family = Family::INET)
super(family, Type::STREAM, Protocol::TCP)
end
# Creates a new TCP connection to a remote TCP server.
#
# You may limit the DNS resolution time with `dns_timeout` and limit the
# connection time to the remote server with `connect_timeout`. Both values
# must be in seconds (integers or floats).
#
# Note that `dns_timeout` is currently ignored.
def initialize(host, port, dns_timeout = nil, connect_timeout = nil)
Addrinfo.tcp(host, port, timeout: dns_timeout) do |addrinfo|
super(addrinfo.family, addrinfo.type, addrinfo.protocol)
connect(addrinfo, timeout: connect_timeout) do |error|
close
error
end
end
end
protected def initialize(family : Family, type : Type, protocol : Protocol)
super family, type, protocol
end
protected def initialize(fd : Handle, family : Family, type : Type, protocol : Protocol)
super fd, family, type, protocol
end
# Creates a TCPSocket from an already configured raw file descriptor
def initialize(*, fd : Handle, family : Family = Family::INET)
super fd, family, Type::STREAM, Protocol::TCP
end
# Opens a TCP socket to a remote TCP server, yields it to the block, then
# eventually closes the socket when the block returns.
#
# Returns the value of the block.
def self.open(host, port)
sock = new(host, port)
begin
yield sock
ensure
sock.close
end
end
# Returns `true` if the Nagle algorithm is disabled.
def tcp_nodelay? : Bool
getsockopt_bool LibC::TCP_NODELAY, level: Protocol::TCP
end
# Disables the Nagle algorithm when set to `true`, otherwise enables it.
def tcp_nodelay=(val : Bool)
setsockopt_bool LibC::TCP_NODELAY, val, level: Protocol::TCP
end
# The amount of time in seconds the connection must be idle before sending keepalive probes.
def tcp_keepalive_idle
system_tcp_keepalive_idle
end
def tcp_keepalive_idle=(val : Int)
self.system_tcp_keepalive_idle = val
end
# The amount of time in seconds between keepalive probes.
def tcp_keepalive_interval
system_tcp_keepalive_interval
end
def tcp_keepalive_interval=(val : Int)
self.system_tcp_keepalive_interval = val
val
end
# The number of probes sent, without response before dropping the connection.
def tcp_keepalive_count
system_tcp_keepalive_count
end
def tcp_keepalive_count=(val : Int)
self.system_tcp_keepalive_count = val
end
end