1. Send multiple wsarecv messages for processing at the same time. What is the redundant situation?
UseCodeTest: The result shows that all error 997 is returned, indicating that the Recv operation can be normally sent, and multiple worker threads are simultaneously detecting multiple Recv messages of this socket, immediately shut down the client after running for a moment, and the closesocket function of one or two worker threads fails to be called. The error code is 10038, therefore, we should try our best to avoid sending duplicate information to the same socket to the completion port. When receiving data, there is no repetition (internal synchronization). That is to say, there is a small possibility of no error only when the socket is disconnected, which is related to thread scheduling.
The test code is as follows:Server:
(Listening thread)
......
// Connection established with client
While (1)
{
While (wsarecv (accept, & (periodata-> databuf), 1, & recvbytes, & flags,
& (Periodata-> overlapped), null) = socket_error & wsagetlasterror () = error_io_pending)
{
Printf ("wsarecv () 2 failed with error % d/N", wsagetlasterror ());
Sleep (1000 );
}
Printf ("wsarecv () succeed! /N ");
Sleep (5000 );
}
......
(Working thread)
......
While (true)
{
// A message is sent to the completed port.
If (getqueuedcompletionstatus (completionport, & bytestransferred,
(Lpdword) & perhandledata, (lpoverlapped *) & periodata, infinite) = 0) // other data members of periodata are filled when the function receives data.
{
If (getlasterror () = 64) // The socket is invalid. Someone has dropped.
{
Printf ("invalid socket % d was closed! /N ", perhandledata-> socket );
If (closesocket (perhandledata-> socket) = socket_error)
{
Printf ("closesocket () failed with error % d/N", wsagetlasterror ());
Return 0;
}
Globalfree (perhandledata );
Globalfree (periodata );
Printf ("periodata at % d was freed! /N ", periodata );
Continue;
}
}
Printf ("getqueuedcompletionstatus () returns bytestransferred = % d/N", bytestransferred );//------
Printf ("periodata-> databuf. Buf = % s/n", periodata-> databuf. BUF );
Printf ("completion routine running ---------/N ");
}
Client:
......
// Connect to the server
While (1)
{
// Obtain the keyboard input and save it
Cin> lpperiodata-> buffer;
Lpperiodata-> databuf. Buf = lpperiodata-> buffer;
Lpperiodata-> databuf. Len = data_bufsize;
// Send data
If (wsasend (client, & (lpperiodata-> databuf), 1, & (lpperiodata-> bytessend ),
0, & (lpperiodata-> overlapped), null) = socket_error)
{
Printf ("wsasend () failed with error % d/N", wsagetlasterror ());
Sleep (1000 );
Return;
}
Else
Printf ("Send succeed! /N ");
Sleep (5000 );
}
For more information, see the image.
2. Send multiple wsasend messages simultaneously for processing
Because the message is asynchronous, 0 is often returned immediately after the message is successfully sent. However, when the internal service thread (not the worker thread) of the port is completed) A 997 error should be returned when many messages are to be processed. Therefore, wsasend messages may be accumulated in unfinished message queues, if the service thread executes the send operation for the same socket at the same time "may" (I guess), it will cause data confusion. Therefore, wsasend should not be called repeatedly to send messages.
3. Send wsarecv and wsasend messages simultaneously
the two do not conflict.