我正在编写一个小型3服务器和1个客户端程序。 2个服务器发送tcp消息,最后一个使用winsock2发送upd数据报。
我想知道我是否可以通过使用线程(OpenMP或boost :: threads)来模拟recvfrom(),以便2个线程同时从同一端口上的同一个套接字进行侦听。
我在windows7上使用VC ++ 2010。
感谢您的帮助。
答案 0 :(得分:7)
是的,套接字是线程安全的,但是你必须要小心。一种常见的模式(当使用阻塞IO时)是让一个线程在套接字上接收数据而另一个线程在同一个套接字上发送数据。让多个线程从套接字接收数据通常适用于UDP套接字,但对大多数时候TCP套接字没有多大意义。 WSARecv的文档中有警告:
不应同时在同一个套接字上调用WSARecv 不同的线程,因为它可能导致不可预测的缓冲区 顺序。
但是如果你使用的是UDP并且协议是无状态的,那么这通常没有任何问题。
另请注意,WSAEINPROGRESS
错误代码主要适用于Winsock 1.1:
WSAEINPROGRESS:正在阻止Windows Sockets 1.1调用,或者服务提供程序仍在处理回调函数。
WSAEINPROGRESS
的描述进一步指出:
正在进行中的操作。
当前正在执行阻止操作。 Windows套接字只允许单个阻塞操作 - 每个任务或线程 - 未完成,如果进行任何其他函数调用(无论它是否引用该套接字或任何其他套接字),该函数将失败并显示WSAEINPROGRESS。
请注意,这涉及每个任务或线程的单个阻塞操作。
此外,WSARecv的文档中还有一个警告:
在APC内发出另一个阻塞Winsock调用,该调用在同一个线程上中断正在进行的阻塞Winsock调用将导致未定义的行为,并且Winsock客户端绝不能尝试。
但除了那些警告你应该没事。
更新:添加一些外部参考: alt.winsock.programming: Is socket thread-safe? 和Winsock Programmer’s FAQ: Is Winsock thread-safe?
答案 1 :(得分:1)
Winsock只允许在套接字上进行一次阻塞IO调用。来自不同线程的多个阻塞调用最终会出现“WSAEINPROGRESS”错误。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx#WSAEINPROGRESS
如果要进行并发IO请求,可以尝试使用异步IO或重叠IO(在Windows用法中)。但我想你会希望并发处理数据而不是并发读取数据。在这种情况下,您可以让一个线程发出IO请求,其他线程进行处理。