FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Proper handling of nonblocking sockets?

 
Post new topic   Reply to topic     Forum Index -> Tutorials
View previous topic :: View next topic  
Author Message
ADmiral



Joined: 17 Jul 2007
Posts: 1

PostPosted: Wed Jul 18, 2007 7:30 am    Post subject: Proper handling of nonblocking sockets? Reply with quote

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 Embarassed

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?)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Tutorials All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group