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