X-Git-Url: http://nitlanguage.org diff --git a/lib/socket/socket.nit b/lib/socket/socket.nit index 26d9937..a40cc5d 100644 --- a/lib/socket/socket.nit +++ b/lib/socket/socket.nit @@ -41,9 +41,9 @@ end # Simple communication stream with a remote socket class TCPStream super Socket - super BufferedIStream - super OStream - super PollableIStream + super BufferedReader + super Writer + super PollableReader # Real canonical name of the host to which `self` is connected var host: String @@ -57,7 +57,7 @@ class TCPStream # Creates a socket connection to host `host` on port `port` init connect(host: String, port: Int) do - _buffer = new FlatBuffer + _buffer = new NativeString(1024) _buffer_pos = 0 socket = new NativeSocket.socket(new NativeSocketAddressFamilies.af_inet, new NativeSocketTypes.sock_stream, new NativeSocketProtocolFamilies.pf_null) @@ -66,21 +66,40 @@ class TCPStream closed = true return end - socket.setsockopt(new NativeSocketOptLevels.socket, new NativeSocketOptNames.reuseaddr, 1) - var hostname = socket.gethostbyname(host) - addrin = new NativeSocketAddrIn.with_hostent(hostname, port) + if not socket.setsockopt(new NativeSocketOptLevels.socket, new NativeSocketOptNames.reuseaddr, 1) then + end_reached = true + closed = true + return + end + + var hostname = sys.gethostbyname(host.to_cstring) + if hostname.address_is_null then + # Error in name lookup + var err = sys.h_errno + last_error = new IOError(err.to_s) + closed = true + end_reached = true + + return + end + + addrin = new NativeSocketAddrIn.with_hostent(hostname, port) address = addrin.address init(addrin.port, hostname.h_name) closed = not internal_connect end_reached = closed + if closed then + # Connection failed + last_error = new IOError(errno.strerror) + end end # Creates a client socket, this is meant to be used by accept only private init server_side(h: SocketAcceptResult) do - _buffer = new FlatBuffer + _buffer = new NativeString(1024) _buffer_pos = 0 socket = h.socket addrin = h.addr_in @@ -106,8 +125,8 @@ class TCPStream # timeout : Time in milliseconds before stopping to wait for events fun ready_to_read(timeout: Int): Bool do - if _buffer_pos < _buffer.length then return true - if eof then return false + if _buffer_pos < _buffer_length then return true + if end_reached then return false var events = [new NativeSocketPollValues.pollin] return pollin(events, timeout).length != 0 end @@ -137,12 +156,23 @@ class TCPStream end # If socket.end_reached, nothing will happen - redef fun write(msg: Text) + redef fun write(msg) do if closed then return socket.write(msg.to_s) end + redef fun write_byte(value) + do + if closed then return + socket.write_byte value + end + + redef fun write_bytes(s) do + if closed then return + socket.write(s.to_s) + end + fun write_ln(msg: Text) do if end_reached then return @@ -152,7 +182,7 @@ class TCPStream redef fun fill_buffer do - _buffer.clear + _buffer_length = 0 _buffer_pos = 0 if not connected then return var read = socket.read @@ -160,7 +190,17 @@ class TCPStream close end_reached = true end - _buffer.append(read) + enlarge(_buffer_length + read.length) + read.copy_to_native(_buffer, read.length, 0, 0) + _buffer_length = read.length + end + + fun enlarge(len: Int) do + if _buffer_capacity >= len then return + while _buffer_capacity < len do _buffer_capacity = _buffer_capacity * 2 + 2 + var ns = new NativeString(_buffer_capacity) + _buffer.copy_to(ns, _buffer_length - _buffer_pos, _buffer_pos, 0) + _buffer = ns end redef fun close @@ -168,14 +208,17 @@ class TCPStream if closed then return if socket.close >= 0 then closed = true + end_reached = true end end # Send the data present in the socket buffer fun flush do - socket.setsockopt(new NativeSocketOptLevels.tcp, new NativeSocketOptNames.tcp_nodelay, 1) - socket.setsockopt(new NativeSocketOptLevels.tcp, new NativeSocketOptNames.tcp_nodelay, 0) + if not socket.setsockopt(new NativeSocketOptLevels.tcp, new NativeSocketOptNames.tcp_nodelay, 1) or + not socket.setsockopt(new NativeSocketOptLevels.tcp, new NativeSocketOptNames.tcp_nodelay, 0) then + closed = true + end end end @@ -193,8 +236,11 @@ class TCPServer socket = new NativeSocket.socket(new NativeSocketAddressFamilies.af_inet, new NativeSocketTypes.sock_stream, new NativeSocketProtocolFamilies.pf_null) assert not socket.address_is_null - socket.setsockopt(new NativeSocketOptLevels.socket, new NativeSocketOptNames.reuseaddr, 1) - addrin = new NativeSocketAddrIn.with(port, new NativeSocketAddressFamilies.af_inet) + if not socket.setsockopt(new NativeSocketOptLevels.socket, new NativeSocketOptNames.reuseaddr, 1) then + closed = true + return + end + addrin = new NativeSocketAddrIn.with_port(port, new NativeSocketAddressFamilies.af_inet) address = addrin.address # Bind it