ADmiral
Joined: 17 Jul 2007 Posts: 1
|
Posted: Wed Jul 18, 2007 7:30 am Post subject: Proper handling of nonblocking sockets? |
|
|
My experience with sockets so far only covers the most basic socket operations in C and Java (which I learned at school). Now I tried to write a basic echo-server and client in D and got it working. Anything typed into the console will get sent to the server, returned and displayed again.
The next thing I want to do is make the client use a nonblocking socket. Right now it's rather pointless because the console still blocks, but I wanted a proof-of-concept to base further development on.
This is the (client) code I got so far:
Code: | import std.stdio;
import std.socket;
int main ( ) {
// Setup
Socket sock = new TcpSocket;
scope (exit) sock.close();
sock.blocking = false;
sock.connect (new InternetAddress ("127.0.0.1", 4711));
while (sock.isAlive()) {
// Get input from console and transmit it
byte[] input = cast(byte[])readln();
int len = sock.send (input);
// Try to handle errors
if ((len == sock.ERROR) && !sock.isAlive()) {
writefln ("Error on send: %d", sock.ERROR); return 1;
}
if (len > 0) writefln("Sent [%d]: %s", len, cast(char[])(input[0..len]));
// Receive the answer if there is one.
len = sock.receive (input);
// Receive error handling
if ((len == sock.ERROR) && !sock.isAlive()) {
writefln ("Error on receive: %d", sock.ERROR); return 1;
}
if (len > 0) writefln("Received [%d]: %s", len, cast(char[])(input[0..len]));
}
return 0;
} |
My problem is this: At first everything works alright, I can send and receive text messages. (I know that returned messages print after the next sent message which looks strange on the console, but I don't care - for the purposes of this example) Also, if the server closes the connection, the client will also leave the loop and exit. But if I kill the server with Ctrl+C or the task manager, there is no sign of a lost connection!
When using blocking sockets, I still get -1 from receive() to indicate a transmission error. But with nonblocking sockets, that's just the value I get when the server hasn't sent anything yet. Also, isAlive() still indicates a connected socket when in fact, the server has closed.
I know that for the server, I could use a SocketSet like in the listener.d sample because that class seems to not have any problems telling the difference between an idle connection and a broken one. But it seems weird to use this method for my single client socket, so I haven't even tried
What is the right way to use nonblocking sockets?
How can I distinguish between idle and broken connections?
Do I have to use threads? (another strange chapter in D, where's my Mutex?) |
|