On Tue, 27 Sep 2011 01:40:49 +0100, Andrea Fontana <[email protected]> wrote:

I'll try to explain it better.

if i write:

socket.send(...);
socket.close();
socket = null;

and send is async, i guess sending will not work properly in this way.

How do i know if send() is still sending or not?

I am not sure of the D socket API, but here is how you do it with the underlying BSD sockets API..

The recommended 'graceful' way to close sockets is to use shutdown(SEND) and then wait on recv/select until the remote end has read all the data and signalled shutdown back, for example..

[endpoint-1] .. wants to send and close:

  send(s..);                // send last response
  .. read any expected replies..
shutdown(s, SD_SEND); // tell the other end you will send no more data .. call recv, if != 0; check for WSAEWOULDBLOCK/EWOULDBLOCK, call select, loop until recv returns 0 ..
  close(s);                 // close


[endpoint-2] .. will react to this in the following way:

  some_loop()
  {
    bytes = recv(s..);      // reading data..
    if(bytes == 0) break;   // no more data
    else if(bytes == SOCKET_ERROR) .. call select, loop ..
    ..etc..
  }
shutdown(s, SD_SEND); // tell the other end you will send no more data .. call recv, if != 0; check for WSAEWOULDBLOCK/EWOULDBLOCK, call select, loop until recv returns 0 ..
  close(s);                 // close

So.. recv returns 0 if the other calls shutdown(SD_SEND) or close(), so even if endpoint-2 is badly behaved and just calls close you will notice - you just might get a "connection reset" error. With non blocking sockets recv returns immediately with SOCKET_ERROR (-1) if there is no data, and the "last error" will be EWOULDBLOCK, in which case you can sleep or select and retry the recv until you get a return of 0, meaning socket closed.

If you don't do this, and call close too soon the remote end will get a 'connection reset by peer' error, due to the locally buffered (unsent) data.

R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/

Reply via email to