The IOCP server serves connections via the WebSocket protocol. When the browser sends a control Close-frame (terminates the connection), the server deletes its client instance, but for some reason GetQueuedCompletionStatus continues to select this client into the completion key, while the call to this function fails and 0 bytes are transmitted.
Here is part of the workflow cycle:
while(WAIT_OBJECT_0 != WaitForSingleObject(EventShutdown, 0)){ DWORD BytesTransfered = 0; OVERLAPPED *asyncinfo = nullptr; client *Client = nullptr; BOOL QCS = GetQueuedCompletionStatus(hIOCP, &BytesTransfered, (PULONG_PTR)&Client, &asyncinfo, INFINITE); if(!Client ) break; switch( QCS * (BytesTransfered > 0) * Client->OpCode() ){ case OP_TYPE_RECV:{ ..... switch( recv_buf[0] &0xFF ){ .... case FIN_CLOSE: printf("FIN_CLOSE on client %u\n", Client->Socket()); default:{ RemoveClient(Client); break; } } } case OP_TYPE_SEND:{ ... } default:{ printf("Client %u (%lu bytes transferred, QCS is %d)\n", Client->Socket(), BytesTransfered, QCS); break; } But the server log:
Client 296 from 127.0.0.1 (agent 1987)
Client 308 from 127.0.0.1 (supervisor)
Client 324 from 127.0.0.1 (supervisor)
TOTAL: 3 client (s)
Sending 33278 bytes to 324
Send finished for 324
Send finished for 308
Sending 40529 bytes to 324
Send finished for 324
Sending 41128 bytes to 324
Send finished for 324
Sending 40430 bytes to 324
Send finished for 324
FIN_CLOSE on client 324
Client 324 deleted
Client 324 (0 bytes transferred, QCS is 0)
Client 324 (0 bytes transferred, QCS is 0)
Client 324 (0 bytes transferred, QCS is 0)
Client 324 (0 bytes transferred, QCS is 0)
Client 324 (0 bytes transferred, QCS is 0)
The 324th sent FIN close, the message " Client 324 deleted " displays the destructor of the object, which is called delete after it has been deleted from the clients vector. After that, the message " Client 324 (0 bytes transferred, QCS is 0) " means that GetQueuedCompletionStatus selects this remote client into the completion key, and with the correct socket ID. How is that even possible? Naturally the server crashes. Maybe I do not understand something in the work of this function? Please explain what is happening ??
PS: for debugging purposes, the server has one workflow.