Class: TCPTimeout::TCPSocket
- Defined in:
- lib/handset_detection/vendor/tcp_timeout.rb
Instance Method Summary collapse
- #connect ⇒ Object
-
#initialize(host, port, opts = {}) ⇒ TCPSocket
constructor
A new instance of TCPSocket.
- #read(length = nil, *args) ⇒ Object
- #readbyte ⇒ Object
- #readpartial(length, *args) ⇒ Object
- #write(data, timeout = nil) ⇒ Object
Constructor Details
#initialize(host, port, opts = {}) ⇒ TCPSocket
Returns a new instance of TCPSocket.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/handset_detection/vendor/tcp_timeout.rb', line 27 def initialize(host, port, opts = {}) @connect_timeout = opts[:connect_timeout] @write_timeout = opts[:write_timeout] @read_timeout = opts[:read_timeout] family = opts[:family] || Socket::AF_INET address = Socket.getaddrinfo(host, nil, family).first[3] @sockaddr = Socket.pack_sockaddr_in(port, address) @socket = Socket.new(family, Socket::SOCK_STREAM, 0) @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) local_host = opts[:local_host] local_port = opts[:local_port] if local_host || local_port local_host ||= '' local_address = Socket.getaddrinfo(local_host, nil, family).first[3] local_sockaddr = Socket.pack_sockaddr_in(local_port, local_address) @socket.bind(local_sockaddr) end connect end |
Instance Method Details
#connect ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/handset_detection/vendor/tcp_timeout.rb', line 51 def connect return @socket.connect(@sockaddr) unless @connect_timeout begin @socket.connect_nonblock(@sockaddr) rescue Errno::EINPROGRESS select_timeout(:connect, @connect_timeout) # If there was a failure this will raise an Error begin @socket.connect_nonblock(@sockaddr) rescue Errno::EISCONN # Successfully connected end end end |
#read(length = nil, *args) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/handset_detection/vendor/tcp_timeout.rb', line 88 def read(length = nil, *args) raise ArgumentError, 'too many arguments' if args.length > 2 timeout = (args.length > 1) ? args.pop : @read_timeout return @socket.read(length, *args) unless length > 0 && timeout buffer = args.first || ''.force_encoding(Encoding::ASCII_8BIT) begin # Drain internal buffers @socket.read_nonblock(length, buffer) return buffer if buffer.bytesize >= length rescue Errno::EWOULDBLOCK, Errno::EAGAIN # Internal buffers were empty buffer.clear rescue EOFError return nil end @chunk ||= ''.force_encoding(Encoding::ASCII_8BIT) loop do timeout = select_timeout(:read, timeout) begin @socket.read_nonblock(length, @chunk) rescue Errno::EWOULDBLOCK, Errno::EAGAIN retry rescue EOFError return buffer.empty? ? nil : buffer end buffer << @chunk if length length -= @chunk.bytesize return buffer if length <= 0 end end end |
#readbyte ⇒ Object
142 143 144 |
# File 'lib/handset_detection/vendor/tcp_timeout.rb', line 142 def readbyte readpartial(1).ord end |
#readpartial(length, *args) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/handset_detection/vendor/tcp_timeout.rb', line 128 def readpartial(length, *args) raise ArgumentError, 'too many arguments' if args.length > 2 timeout = (args.length > 1) ? args.pop : @read_timeout return @socket.readpartial(length, *args) unless length > 0 && timeout begin @socket.read_nonblock(length, *args) rescue Errno::EWOULDBLOCK, Errno::EAGAIN timeout = select_timeout(:read, timeout) retry end end |
#write(data, timeout = nil) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/handset_detection/vendor/tcp_timeout.rb', line 67 def write(data, timeout = nil) timeout ||= @write_timeout return @socket.write(data) unless timeout length = data.bytesize total_count = 0 loop do begin count = @socket.write_nonblock(data) rescue Errno::EWOULDBLOCK, Errno::EAGAIN timeout = select_timeout(:write, timeout) retry end total_count += count return total_count if total_count >= length data = data.byteslice(count..-1) end end |