digitalmars.D.learn - Socket: Detect connection close
- nrgyzer (72/72) Mar 23 2014 Hi guys,
- "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> (8/8) Mar 23 2014 In Java, the only way to know is to attempt to send something. I
- "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> (2/6) Mar 23 2014 I wouldn't write any code using it.
- Vladimir Panteleev (3/74) Mar 23 2014 You can determine when the connection was closed on the remote
- nrgyzer (18/109) Mar 24 2014 Alright, that world work. But what about sending 10 Bytes,
- Vladimir Panteleev (18/34) Mar 24 2014 Yes. Unless your socket is marked as non-blocking, the read
Hi guys, I'm experimenting with sockets and having trouble to detect when the remote side closes the connection. Here's my code: // Client: module client; import std.socket; void main() { TcpSocket s = new TcpSocket(); s.connect(new InternetAddress("localhost", 8080)); SocketStream ss = new SocketStream(s); for (int i= 0; i < 10; i++) { ss.write(1); ss.flush(); } ss.socket.shutdown(SocketShutdown.BOTH); ss.close(); } // Server: module server; import std.sdio; import std.socket; void main() { TcpSocket s = new TcpSocket(AddressFamily.INET); s.bind(new InternetAddress("localhost", 8080)); s.blocking(false); s.listen(0); while(1) { try { Socket requestSocket = oSocket.accept(); RequestThread rt = new RequestThread(requestSocket); rt.start(); } catch (SocketAcceptException e) { Thread.yield(); } } s.socket.shutdown(SocketShutdown.BOTH); s.close(); } class RequestThread : Thread { private { __gshared Socket s; void run() { ubyte[1] buffer; while(s.isAlive) { s.receive(buffer); writeln("receiving"); } writeln("client closed connection"); } } public this(Socket socket) { super(&run); s = socket; } } I know... dirty (really) dirty code, but it works , except that I'm in an endless loop and my server always prints "receiving". I never see "client closed connection" although the client sends only 10 int values. It seems that "s.isAlive" is always true. How can I detect when the client closes the connection (or how can I detect if the connection is broken)? Thanks for any suggestions or ideas!
Mar 23 2014
In Java, the only way to know is to attempt to send something. I presume it's limited that way because the OS's don't provide more info, or because TCP itself does not tell if a connection has closed unless something is sent. I could be wrong, but all my network code in other languages rely on sending stuff to register a closed connection. For connections that are open for a very long time with low throughput I send small packages regularly just to be sure it's still open.
Mar 23 2014
Also, SocketStream: http://dlang.org/phobos/std_socketstream.htmlWarning: This module is considered out-dated and not up to Phobos' current standards. It will remain until we have a suitable replacement, but be aware that it will not remain long term.I wouldn't write any code using it.
Mar 23 2014
On Sunday, 23 March 2014 at 20:12:38 UTC, nrgyzer wrote:Hi guys, I'm experimenting with sockets and having trouble to detect when the remote side closes the connection. Here's my code: // Client: module client; import std.socket; void main() { TcpSocket s = new TcpSocket(); s.connect(new InternetAddress("localhost", 8080)); SocketStream ss = new SocketStream(s); for (int i= 0; i < 10; i++) { ss.write(1); ss.flush(); } ss.socket.shutdown(SocketShutdown.BOTH); ss.close(); } // Server: module server; import std.sdio; import std.socket; void main() { TcpSocket s = new TcpSocket(AddressFamily.INET); s.bind(new InternetAddress("localhost", 8080)); s.blocking(false); s.listen(0); while(1) { try { Socket requestSocket = oSocket.accept(); RequestThread rt = new RequestThread(requestSocket); rt.start(); } catch (SocketAcceptException e) { Thread.yield(); } } s.socket.shutdown(SocketShutdown.BOTH); s.close(); } class RequestThread : Thread { private { __gshared Socket s; void run() { ubyte[1] buffer; while(s.isAlive) { s.receive(buffer); writeln("receiving"); } writeln("client closed connection"); } } public this(Socket socket) { super(&run); s = socket; } } I know... dirty (really) dirty code, but it works , except that I'm in an endless loop and my server always prints "receiving". I never see "client closed connection" although the client sends only 10 int values. It seems that "s.isAlive" is always true. How can I detect when the client closes the connection (or how can I detect if the connection is broken)?You can determine when the connection was closed on the remote side by checking if s.receive returns an empty array.
Mar 23 2014
On Monday, 24 March 2014 at 05:32:30 UTC, Vladimir Panteleev wrote:On Sunday, 23 March 2014 at 20:12:38 UTC, nrgyzer wrote:Alright, that world work. But what about sending 10 Bytes, waiting some minutes (probably some hours) and sending 10 Bytes again. Is it possible to do this on the same Socket? My scenario is: I've one central server and multiple clients. The clients are connecting to the server and send (or request) some information. After that the clients are simply "sleeping" for an unknown time. For instance client 1 for 1 seconds, client 2 for 1 minute, client 3 for 1 hours and client 4 for 1 day. After that time they resend/request some more information from the server... my questions regarding this are: - When I client connects, the server creates a thread. How can I determine that I can terminate the thread because the connection is inactive (for instance because the client closed the connection or some connecting issues)? - How can the client check if the connection is alive? (If the connection isn't alive, I need to reconnect)Hi guys, I'm experimenting with sockets and having trouble to detect when the remote side closes the connection. Here's my code: // Client: module client; import std.socket; void main() { TcpSocket s = new TcpSocket(); s.connect(new InternetAddress("localhost", 8080)); SocketStream ss = new SocketStream(s); for (int i= 0; i < 10; i++) { ss.write(1); ss.flush(); } ss.socket.shutdown(SocketShutdown.BOTH); ss.close(); } // Server: module server; import std.sdio; import std.socket; void main() { TcpSocket s = new TcpSocket(AddressFamily.INET); s.bind(new InternetAddress("localhost", 8080)); s.blocking(false); s.listen(0); while(1) { try { Socket requestSocket = oSocket.accept(); RequestThread rt = new RequestThread(requestSocket); rt.start(); } catch (SocketAcceptException e) { Thread.yield(); } } s.socket.shutdown(SocketShutdown.BOTH); s.close(); } class RequestThread : Thread { private { __gshared Socket s; void run() { ubyte[1] buffer; while(s.isAlive) { s.receive(buffer); writeln("receiving"); } writeln("client closed connection"); } } public this(Socket socket) { super(&run); s = socket; } } I know... dirty (really) dirty code, but it works , except that I'm in an endless loop and my server always prints "receiving". I never see "client closed connection" although the client sends only 10 int values. It seems that "s.isAlive" is always true. How can I detect when the client closes the connection (or how can I detect if the connection is broken)?You can determine when the connection was closed on the remote side by checking if s.receive returns an empty array.
Mar 24 2014
On Monday, 24 March 2014 at 18:06:56 UTC, nrgyzer wrote:Alright, that world work. But what about sending 10 Bytes, waiting some minutes (probably some hours) and sending 10 Bytes again. Is it possible to do this on the same Socket?Yes. Unless your socket is marked as non-blocking, the read operation will block until more data is available (or the connection gets closed).My scenario is: I've one central server and multiple clients. The clients are connecting to the server and send (or request) some information. After that the clients are simply "sleeping" for an unknown time. For instance client 1 for 1 seconds, client 2 for 1 minute, client 3 for 1 hours and client 4 for 1 day. After that time they resend/request some more information from the server... my questions regarding this are: - When I client connects, the server creates a thread. How can I determine that I can terminate the thread because the connection is inactive (for instance because the client closed the connection or some connecting issues)?As mentioned previously, you know that the connection was closed cleanly on the remote side when receive returns an empty buffer.- How can the client check if the connection is alive? (If the connection isn't alive, I need to reconnect)You generally have to implement this yourself. Silence on the wire can mean two things: 1. No data is being sent; 2. Something is preventing data from being sent (lost packets, a peer was shut down or restarted, Internet routing changes, squirrel chewed through a wire). Generally network software implements "ping" packets that are sent occasionally (once every few seconds or minutes). If no "ping" packets are received throughout a certain interval, the connection is considered dead. TCP also has a "keepalive" option which does this for you, but it is an optional TCP feature and thus may or may not work.
Mar 24 2014