Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

ServerSocket.accept and threading it

Moderators: larsivi kris

Posted: 03/28/09 21:13:39

I am trying to make a server that accepts multiple connections and am completely new to doing any type of socket programming. I understand that the ServerSocket?.accept function just sits there and loops until someone tries to connect. Since it does this and I want the server to be able to do other things than sit there and wait for connections, I put the ServerSocket?.accept function into a thread that waits for connections and adds them to my list of connections when they are accepted/validated.

The problem I am having is, when I send the server shutdown command from the client, the main thread of the server shuts down, but the thread that waits for connections keeps waiting until one is made. Once one is made at that point it seg faults b/c the connections array no longer exists... I know that the thread continues to run b/c of the ServerSocket?.accept function just sits there and loops, is there any way to force that function to quit or gather a que of connections instead of just sitting there waiting for more? (built in...) I want all the threads to be shut down when the main thread shuts down...

Author Message

Posted: 03/28/09 22:26:22

you need to somehow interrupt the waiting thread, or arrest it before it returns to accept(). There's probably a dozen or more application-specific ways to achieve that, depending on how your code is structured and what the throughput expectations are.

There's no explicitly normal way to kill a secondary thread, other than perhaps to terminate your process using the C library exit() function or similar. Another approach might be to close the accept() socket handle, and see if that interrupts the accept() call (instead of it waiting for another connection).

As an aside, pretty much any graceful exit from a thread will require the thread to inspect its environment for termination conditions, and continue or return appropriately. For example: your accept() thread should perhaps test a boolean indicator (or equivalent, representing liveness) before it tries to access the connection array. If the flag is set, that thread should likely return instead.

Hope that helps

Posted: 03/29/09 00:18:15

Ok, that helped a little and I have the sub thread closing properly now. Another thing I was wondering, is there a way to send more than 1 packet without getting something back?

When I try this: SocketConduitVariable?.output.write(packetVariable); SocketConduitVariable?.output.write(packetVariable);

All of the packets get lumped into 1 thing (Tested with raw strings) when I do SocketConduitVariable?.input.read(packetVariable) on the other side.

Is there a way to force the write to send the packet so i don't have to wait on a confirmation that it was received on the other side? I'm assuming of course that the write/read functions are que'd in some fashion.

Posted: 03/29/09 02:15:28

If you're not using BufferedOutput, and just writing directly to the conduit, then you're likely bumping into the Nagle socket setting. It's generally quite expensive to send lots of small packets, so the O/S has this mode whereby socket output can be delayed slightly in case some additional output can be piggy-backed onto the same packet.

There's a method in Socket called setNoDelay(bool), which should help. On each of your client connections, set it true so there's no delay in the outbound packets. To reach that from a SocketConduit, do this:

socketConduitVariable.socket.setNoDelay(true);

Posted: 03/29/09 04:35:05 -- Modified: 03/29/09 04:39:08 by
wolftousen

ok, i'll try that out here in a bit. I did come across something I find odd though. When i send the server the shutdown command now, i go through all my connections and do .shutdown and .close on the server side and send them a msg saying the server is shutting down.

I know that i should interpret that message on the client side, but for now i'm ignoring it and just continue as though I was still connected.

On client side, after server shutdown, when I do 1 more socketconduit.output.write, i get the expected Eof value. If I do it 1 more time after that, my client unexpectedly shuts down and throws no exceptions and gives no errors. I tried using the socketconduit.isAlive, but it always returns true no matter what.

In the documentation, it sounds like .shutdown sends a signal to the other end of the connection from where it is called. If it does, how do I read this signal (I assumed this was for .isAlive...)

Does socketconduit.output.write returning Eof always mean that my socketconduit has lost connection?

Posted: 03/31/09 03:16:13

Kris, it looks like my issue with .isalive is a known issue on linux. that last change log for socket.d? is in 07. Is there any chance you can look into a fix for it that will work again?

Posted: 03/31/09 04:37:36

When Eof is returned from a socket, it typically means the socket is no longer connected. You should test for this condition and perform an appropriate action. The isAlive() method, as you note, is subject to platform-specific issues and will likely be removed because of that.

Regarding shutdown(), it will likely result in an Eof being returned from a read or write operation. Take a look at the raw socket API (in a C library) to see where the limitations are, or one of the many online tutorials (there's one noted in Socket.d)

Posted: 03/31/09 17:40:29

Have you considered using select? That will timeout the wait for the new connection. select returns readable if there is an incoming connection waiting.

tango/io/selector/*

or use the select method on the socket itself.