1

Say, a tcp client has connected to a tcp server on socket s. Next, the client call shutdown(s); then how should the server detect that the client has did that operation?

PS: I have known the server will receive FD_CLOSE. However, I don't know how to check that flag on the server side.

xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • 1
    Take a look at the discussion here: http://stackoverflow.com/questions/3091010/recv-socket-function-returning-data-with-length-as-0 – Forhad Ahmed Feb 08 '13 at 18:48

2 Answers2

4

From winsock's recv description:

If the connection has been gracefully closed, the return value is zero.

Getting zero byte count from recv,WSARecv (or ReadFile) is the common way to learn that the other side has closed the connection.

Anton Kovalenko
  • 20,999
  • 2
  • 37
  • 69
  • Thanks. But a related question follows: How to call recv in non-block way to check that? Does ioctlsocket help? – xmllmx Feb 08 '13 at 18:56
  • @xmllmx: Use `select()` with a timeout. – netcoder Feb 08 '13 at 18:58
  • How would you get data if it *weren't* closed? (You could use overlapped I/O, or non-blocking mode, or `WSAEventSelect`, or `WSAAsyncSelect`, whatever you want. But you surely read the data *somewhere* -- just check for zero byte count in *that* place) – Anton Kovalenko Feb 08 '13 at 19:00
1

xmllmx - Don't call recv() to check if the socket has closed, use select() and ask it to signal when the socket is readable or writable. Note also that unless you're just writing a demo for class you most likely want to set your sockets to non-blocking mode anyway as calling recv() with too big of a buffer will cause it to block, so will causing send() with a buffer that can't fit into the OS's buffer, etc...

Finally, using select() is pretty terrible in Winsock as well; you probably want to use one of the forms of Overlapped I/O, such as completion routines or completion ports.

huntharo
  • 2,616
  • 21
  • 23