Determine the state of a TCP socket

2019-07-12 13:14发布

问题:

I'm starting to learn about how to implement in C++ a TCP server/client (on Windows and Linux). At this moment, I'm implementing the server (and testing with the telnet as client). The server application is sending and recieving data like a charm.. (I will implement the client after understand all the server side). But I need to find a programmatic (C++ or O.S API) way to query the TCP socket state (ESTABLISHED, FIN_WAIT_2, CLOSE_WAIT, etc..) without use the write()/recv() to handle the error exception..

For example:

  1. Server starts, bind the socket and wait a connection
  2. A client starts and connect on the server
  3. Here, I have a loop at the server that use the func "ioctlsocket(socket, FIONREAD, pbytes_available)" to determine when I have data to read..
  4. If the client send some data, then "pbytes_available" will be > 1 and the server use recv() to get.
  5. If the client doesn't sends anything, then the server can do other tasks and check if there are data on the socket at the next loop.
  6. If I close the TELNET (client process) and run the "netstat", I'll see that the server socket is with the "CLOSE_WAIT" state, so I need to close the socket at the server side..

And this is the question: How can I query the TCP socket state to determine that I need close this session? (without use the send()/recv(), like the "netstat" do)

Note: I tried the "getsockopt(socket, SOL_SOCKET, SO_ERROR, &optval, &optlen )", but it return 0 when the state is ESTABLISHED/CLOSE_WAIT and the "optval" also doesn't changes.

回答1:

The usual technique with blocking-mode sockets is to dedicate a thread to reading the socket. When recv() returns 0 it means the peer has closed the connection and the port is now in CLOSE_WAIT state.

Alternatively you can use select() and friends to tell you when the socket is readable, which includes the case where recv() will return zero. Using FIONREAD as a polling mechanism is really pretty useless as it doesn't cover this case.