WIN32 Socket API: Canceling Send/Recv on socket using event-based completion notification

1k Views Asked by At

using socket with the overlapped operation selected the event-based completion notification; Have 2 events, one for data, the other to cancel long send/recv:

 HANDLE events[] = { m_hDataEvent, m_hInterruptEvent };

then calling WSASend,

 WSASend(m_Socket, &DataBuf, 1, NULL, 0, &SendOverlapped, NULL);

followed by

 WSAWaitForMultipleEvents(2, events, FALSE, INFINITE, FALSE);

which is setup to return on any one event signaled. Now assume send is in progress, and m_hInterruptEvent is signaled. WSAWaitForMultipleEvents returns, technically the function calling send can return as well and delete internally allocated buffers.

What is not clear to me, the WSASend may still be working in background, and deleting buffers will cause data corruption in best case.

What would be the proper way to stop the background Send/Receive, if the socket needs to be used for something else immediately?

I looked at the CancelIO(), but the MSDN never mentions it in relation to Sockets, does it work with file based IO only?

1

There are 1 best solutions below

1
On

It makes no sense to try to cancel it once sent. Even if you succeeded you would have a problem because the receiving application would not have any idea that the transmission was interrupted. Your new message will be mistaken for the end of the old message.

If you feel the need to cancel long sends, you should probably look at your application design.

  • Send in chunks and check for cancellation in between chunks. Ensure you have a way of communicating to the receiver that the transmission was cancelled.
  • Close the socket to cancel. Again, ensure the client has a way to know that this is an interrupted transmission (for example if the client knows the total length in advance they will recognise an interrupted transmission).
  • Just wait for it to succeed in the background and don't worry. If you have urgent messages use a separate connection for them.

For your particular question "What would be the proper way to stop the background Send/Receive, if the socket needs to be used for something else immediately", the answer is: Sockets are cheap - Just use two - one for the slow transmission the other for the urgent messages.