+ 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
+
+ # Checks if the socket still is connected
+ fun connected: Bool
+ do
+ if closed then return false
+ var events = [new NativeSocketPollValues.pollhup, new NativeSocketPollValues.pollerr]
+ if pollin(events, 0).length == 0 then
+ return true
+ else
+ closed = true
+ return false
+ end
+ end
+
+ redef fun is_writable do return not end_reached
+
+ # Establishes a connection to socket addrin
+ #
+ # REQUIRES : not self.end_reached
+ private fun internal_connect: Bool
+ do
+ assert not closed
+ return socket.connect(addrin) >= 0
+ end
+
+ # If socket.end_reached, nothing will happen
+ redef fun write(msg: Text)
+ do
+ if closed then return
+ socket.write(msg.to_s)
+ end
+
+ fun write_ln(msg: Text)
+ do
+ if end_reached then return
+ write(msg.to_s)
+ write("\n")
+ end
+
+ redef fun fill_buffer
+ do
+ _buffer.clear
+ _buffer_pos = 0
+ if not connected then return
+ var read = socket.read
+ if read.length == 0 then
+ close
+ end_reached = true
+ end
+ _buffer.append(read)
+ end
+
+ redef fun close
+ do
+ 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
+ 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
+
+# A socket listening on a given `port` for incomming connections
+#
+# Create streams to communicate with clients using `accept`.
+class TCPServer
+ super Socket
+
+ private var addrin: NativeSocketAddrIn is noinit
+
+ # Create and bind a listening server socket on port `port`
+ init
+ do
+ socket = new NativeSocket.socket(new NativeSocketAddressFamilies.af_inet,
+ new NativeSocketTypes.sock_stream, new NativeSocketProtocolFamilies.pf_null)
+ assert not socket.address_is_null
+ if not socket.setsockopt(new NativeSocketOptLevels.socket, new NativeSocketOptNames.reuseaddr, 1) then
+ closed = true
+ return
+ end
+ addrin = new NativeSocketAddrIn.with(port, new NativeSocketAddressFamilies.af_inet)