views:

57

answers:

1

Here is what I am trying to do: The server sends message to connected clients when new messages are available. The client, on the other hand, when connected, tries to send a message to the server using send() and then receive message using recv(), right after that, the client calls close() to close the connection.

Sometimes, after the client finishes, the server tries to receive message from client will result in a 104 - "connection reset by peer" error. When this happens, Wireshark reveals that the last two segments sent by the client is:
1. an ACK acknowledging the receipt of the message sent by the server
2. a RST/ACK
No FIN is sent by the client.

Why is this happening and how can I close the socket "properly" at the client?

+1  A: 

This will occur if you call close() in the client with data still in the receive queue. The client will send RST instead of FIN, as an indication that not all data was successfully delivered to the application. If the connection was only for the benefit of the client then probably the server does not care; since no further communication is possible on that socket the server should simply close it.

This can be avoided by shutting down the connection as follows (where A is the side initiating the shutdown):

  • When A is finished sending all data, it calls shutdown(sock, SHUT_WR) and continues to read from socket.
  • When B sees EOF (e.g. recv() returns 0), it knows A is initiating a shutdown. B sends any final responses or other final data as applicable, calls shutdown(sock, SHUT_WR), and then close(sock).
  • When A sees EOF, if it has already shut down writes it just calls close(sock).

Note that ECONNRESET is still possible, if for example the other process is killed, so it must still be handled. In this case there is no point in sending any final response since the other side will not receive it, so the socket should just be closed in that case.

mark4o
Thanks for the answer. And that's exactly what I encountered. Could you elaborate "when B sees EOF, it knows A is initiating a shutdown"? How should I do in my code for that?
gc
Never mind. I found my answer here (2.6): http://www.faqs.org/faqs/unix-faq/socket/
gc
If you are calling `recv()` or `read()`, these interfaces indicate EOF by returning 0.
mark4o