Socket: Detect connection close

nrgyzer nrgyzer at gmail.com
Mon Mar 24 11:06:55 PDT 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:
>> 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.

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)


More information about the Digitalmars-d-learn mailing list