2

Based on this question, when you call closesocket() on a socket that recv() is already using, then an RST packet will be sent to the other side instead of performing a graceful disconnection (4-way handshake).

But I wish to perform a graceful disconnection, so I need to exit recv() before calling closesocket().

Is there a way to do that?

Community
  • 1
  • 1
  • 2
    You *can't* call `closesocket` on a socket that `recv` is already using. Try to write code to do it, it's pretty much impossible. You would need some way to know that the `recv` had already accessed the socket using some kind of thread context inspection. Your code will inevitably have race conditions in which terrible things can happen. – David Schwartz Mar 10 '15 at 20:01
  • "when you call closesocket() on a socket that recv() is already using, then an RST packet will be sent to the other side" This really is not true. The RST is caused by the act of closing the socket when there is unread pending data. – user207421 Apr 20 '15 at 01:01

2 Answers2

8

You can shutdown() the socket for input. The recv() will unblock and return zero and everybody will be happy.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
user207421
  • 305,947
  • 44
  • 307
  • 483
  • This does not always work, as in http://stackoverflow.com/questions/29737707/exit-a-blocking-recv-call with the right server (that does not accept input). This and David Schwartz comment (a deeper variation of "A Winsock client must never issue closesocket on s concurrently with another Winsock function call.") make me feel that the only solution when shutdown does not work is ... non blocking sockets. – Liviu Jun 21 '15 at 22:54
  • It also does not work if, after connection, a cable is unplugged in a router, effectively cutting the communication, but without immediate effect for the TCP/IP connection (http://stackoverflow.com/questions/13085676/tcp-socket-no-connection-timeout). – Liviu Jun 22 '15 at 00:04
  • @Liviu There is nothing in this answer about calling `closesocket()`, and there is nothing in the links you cite that confirm your claim that shutting down a socket for input doesn't work when a cable is pulled. It is difficult to see any connection between the two events actually. – user207421 Aug 01 '16 at 09:27
  • 1
    Man, I cannot verify your claims one year later (different job, no router)... But, if the (real network) connection is down (by pulling a cable not directly connected to your computer), your `shutdown` won't unblock anything as the blocking socket does not known that the connection is down and it will wait for some timeout (that can be minutes long: it was 2 minutes maybe, for us) – Liviu Aug 01 '16 at 10:17
  • "There is nothing in this answer about calling `closesocket()`". It isn't, but I never said it, isn't it? On the other hand, your (so called) anwser won't work in this case: http://stackoverflow.com/questions/29737707/exit-a-blocking-recv-call. So "How to exit a blocking recv() call?" – Liviu Aug 01 '16 at 10:29
  • 1
    I see now ... you are the "expert" that closed a legitimate question: ["Exit a blocking recv() call"] (http://stackoverflow.com/questions/29737707/exit-a-blocking-recv-call). Have you even bother to test it before saying "Works for everybody else" ? (This site has real troubles, like allowing you to close questions.) – Liviu Aug 01 '16 at 14:32
  • @Liviu It knows that the connection has been shutdown for input, which unblocks it and causes it to return zero. And you oo videoing irrelevant quote containing `closesockst()`. It's up there in black and white. – user207421 Feb 06 '19 at 17:46
  • @ user207421 out of this discussion, sorry, please stop mentioning my name – Liviu Feb 08 '19 at 08:19
  • @Liviu You can't control that. Or the site. – user207421 Dec 03 '19 at 04:49
0

The real issue here is that a sure kill, terminatethread(), has all kinds of warnings on it about bad effects of its use. I have been using this method to exit an recv(). The windows docs says "you must know what the thread is doing before applying terminatethread", well, we know what it is doing, its in recv(). The question is not what the THREAD is doing, its what windows kernel is doing.

In the embedded system RTOSes I have done killthread() is doable. Its not EASY, you have to find every single lock and resource owned by the thread and back it out. Only the OS has that kind of information (and power).

Scott Franco
  • 481
  • 2
  • 15
  • `terminatethread()` is not mentioned in the question. Hard to see why this 'real issue' is relevant. – user207421 Aug 01 '16 at 09:34
  • `terminatethread` can be used as a last resort (when the previous answer, the accepted "solution", does not work) to stop the thread of a blocking socket. – Liviu Aug 01 '16 at 15:00
  • The question was (did you read it?) How to exit a blocking recv() call? terminating the calling thread is one way to do that. – Scott Franco Aug 09 '16 at 18:19