我正在编写一个小型的 3 个服务器和 1 个客户端程序。2台服务器发送tcp消息,最后一台使用winsock2发送upd数据报。
我想知道我是否可以通过使用线程(OpenMP 或 boost::threads)来模拟 recvfrom(),以便 2 个线程同时从同一个端口上的同一个套接字监听。
我在 windows7 上使用 VC++ 2010。
感谢您的帮助。
我正在编写一个小型的 3 个服务器和 1 个客户端程序。2台服务器发送tcp消息,最后一台使用winsock2发送upd数据报。
我想知道我是否可以通过使用线程(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 套接字仅允许单个阻塞操作(每个任务或线程)处于未完成状态,并且如果进行了任何其他函数调用(无论它是否引用该套接字或任何其他套接字),该函数都会失败并出现 WSAEINPROGRESS 错误。
请注意,这涉及每个任务或线程的单个阻塞操作。
此外,WSARecv 的文档中还有一个附加警告:
在 APC 中发出另一个阻塞 Winsock 调用中断了同一线程上正在进行的阻塞 Winsock 调用将导致未定义的行为,并且 Winsock 客户端绝不能尝试。
但除了这些警告之外,你应该没问题。
更新:添加一些外部引用: alt.winsock.programming:套接字线程安全吗? 和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 请求,其他线程进行处理。