4

Windows socket close(closesocket) function generates RST.

On linux when I call close function to close a tcp socket it goes through fin/ack from both client server and the socket gets closed.

But on windows winsock, whenever i call closesocket it always generates RST message.

I tried using shutdown call. It is generating FIN. But finally I have to call closesocket and it sends RST.

Is there a way to call closesocket to release socket resources without sending RST message.

Steve Piercy
  • 13,693
  • 1
  • 44
  • 57
  • 1
    What are you doing before that? Have you read all the incoming data? Have you messed with SO_LINGER on the socket? – user207421 Mar 07 '18 at 22:49
  • ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); iResult = shutdown(ConnectSocket, SD_SEND); closesocket(ConnectSocket); WSACleanup(); I hAve finished receiving all the data. But it looks like to me that windows socket never goes through four way FIN/ACK to close socket. It always sends RST whenever either colsesocket gets called or shutdown called with SD_BOTH. I am looking for a way to four way FIN/ACK on windows socket close as it happens on linux. – deshapriya debesh Mar 07 '18 at 22:59
  • 2
    You should not post code in comments. Add it to your question. But the evidence suggests you haven't read all the incoming data. Did you really `recv()` until you got a zero return? – user207421 Mar 07 '18 at 23:00
  • Sorry for the confusion. You are right. I ain't waiting for recv() to return zero. In my case server is the source and client is the receiver. I have some condition where i want close the client socket. The client socket SO_LINGER is set for (ld.l_onoff = 1, ld.l_linger = 10). on that condition I call shutdown of client socket with SD_SEND and then call closesocket. I expect the client to wait till 10 seconds to read all data and if no data left gracefully close without sending RST. If after 10 seconds there are any data then send RST. – deshapriya debesh Mar 07 '18 at 23:46
  • 1
    Eh? That SO_LINGER setting means that the client will wait up to 10 seconds to *send* all pending data when it closes the socket. The only way it can wait for up to 10 seconds to *receive* data is via SO_RCVTIMEO, or `select()`, and a `recv()` call. – user207421 Mar 08 '18 at 00:20
  • https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-shutdown – bers Jan 03 '23 at 11:58

2 Answers2

2

There are several things that can cause closesocket() to send an RST instead of a FIN:

  1. Calling it when there is unread data pending in the socket receive buffer.
  2. Calling it after you have set the SO_LINGER option to 'on' with a zero timeout.
user207421
  • 305,947
  • 44
  • 307
  • 483
1

If there are no more data to send and/or receive, you can use 'shutdown()'.

Ex: shutdown(clisocket, SD_BOTH);

  • Doesn't answer the question in any way. – user207421 Jun 05 '19 at 10:52
  • @user207421 it does - see https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-shutdown, "To assure that all data is sent and received on a connected socket before it is closed ..." mentions `shutdown`. – bers Jan 03 '23 at 11:59