You are responsible for putting the thread into an alertable state in your own code, ie inside the main thread's message loop.
Would you tell me how ?
I don't know. You would probably have to replace the main message loop with your own message loop. This is a good reason NOT to use alertable I/O in a UI thread in the first place.
The reason I would like to use WSASend is to improve performance. WSASend would send data directly from application buffers, while send performs a copy.
That is incorrect. A
WSASend() operation copies the user's data from the
WSABUF buffers into WinSock's internal buffers. The operation is complete when the data has been copied into the internal buffers, same as with
send(). The actual transmission is done in the background using WinSock's internal buffers, while your code has already been released to move on with other things in the meantime.
The only socket API that actually uses the user-provided buffers internally is
Registered I/O.
Another reason is, Microsoft says about WSAAsyncSelect (needed for message notifications):
[The WSAAsyncSelect function is available for use in the operating systems specified in the Requirements section. It may be altered or unavailable in subsequent versions. Rather than use Select-style I/O, use Overlapped I/O and Event Objects with WinSock2.]
Microsoft is not in the habit of removing deprecated APIs. Also,
WSAAsyncSelect() is not the only way to get socket notifications, but it is the preferred way if you are performing your socket I/O in a UI thread, which you really shouldn't be doing in the first place.
WSAAsyncSelect() dates back to the Windows 3.x days when the whole OS was single-threaded before preemptive multithreading was introduced in Windows 95. But
WSAAsyncSelect() still works just fine in modern Windows versions.
send and the message system does not tell me when whole data has been sent, while CompletionRoutine does.
send() returns the number of bytes copied into WinSock's internal buffer. An I/O completion routine reports the exact same thing. The difference is that
send() may return fewer bytes than requested, requiring you to call
send() again to re-send the remaining data, whereas Overlapped I/O or IOCP tends to handle that internally for you, reporting completion only when all of the requested data is finished. But that is NOT guaranteed, so you should be prepared to handle the possibility that a Completion notification reports fewer bytes than requested, requiring the remaining data to be re-sent again.