Yes, sockets are thread safe, but you have to be careful. One common pattern (when using IO blocking) is to have one stream that receives data on the socket, and another stream that sends data to the same socket. Having multiple streams that receive data from a socket is usually great for a UDP socket, but in most cases it doesn't make much sense for TCP sockets. In the documentation for WSARecv :
WSARecv cannot be used to call different threads simultaneously on the same socket, because this can lead to an unpredictable order buffer.
But this is usually not a concern if you use UDP, and the protocol has no status.
Also note that the WSAEINPROGRESS error code mainly refers to Winsock 1.1:
WSAEINPROGRESS: Windows Sockets 1.1 calls are being blocked or the service provider is still processing the callback function.
And the WSAEINPROGRESS description further states:
The operation is in progress.
The lock operation is in progress. On Windows Sockets, only one lock operation is allowed per task or thread, and if any other function call is made (regardless of whether it refers to this or any other socket), the function fails with a WSAEINPROGRESS error.
Note that this indicates one lock operation for each task or thread.
In addition, the documentation for WSARecv has an additional warning:
Issuing another Winsock blocking call within the APC that interrupted the current Winsock blocking call in the same thread will result in undefined behavior and will never be attempted by Winsock clients.
But besides these warnings you should be fine.
Update: to add some external links: alt.winsock.programming: Does it contain a ceiling? and Frequently Asked Questions for Winsock Programmers: Is Winsock Safe?