我正在写一个小的3个服务器和1个客户端程序。两台服务器发送tcp消息,最后一台服务器使用winsock2发送更新数据报。
我想知道我是否可以使用线程(OpenMP或boost:: threads )来模拟recvfrom(),以便两个线程同时侦听同一端口上的同一套接字。
我在windows7上使用VC++ 2010。
谢谢你的帮助。
发布于 2012-12-21 18:11:13
是的,套接字是线程安全的,但是你必须小心。一种常见的模式(当使用阻塞IO时)是让一个线程在一个套接字上接收数据,另一个线程在同一套接字上发送数据。让多个线程从一个套接字接收数据通常对于UDP套接字来说是很好的,但是对于TCP套接字来说在大多数情况下没有多大意义。WSARecv的文档中有一个警告
不应从不同的线程同时在同一套接字上调用
WSARecv,因为这可能会导致不可预知的缓冲区顺序。
但是,如果您使用的是UDP,并且协议是无状态的,那么这通常不是什么问题。
还要注意,WSAEINPROGRESS错误代码主要适用于Winsock1.1:
WSAEINPROGRESS:阻塞的
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?
发布于 2012-12-21 10:48:13
Winsock只允许一个套接字上有一个阻塞IO调用。来自不同线程的多个阻塞调用将以"WSAEINPROGRESS“错误结束。http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx#WSAEINPROGRESS。
如果您想进行并发IO请求,您可以尝试使用异步IO或重叠IO (在windows术语中)。但是我猜你可能更希望并发处理数据而不是并发读取数据。在这种情况下,您可以让一个线程发出IO请求,而让其他线程进行处理。
https://stackoverflow.com/questions/13983398
复制相似问题