5

我正在编写一个小型的 3 个服务器和 1 个客户端程序。2台服务器发送tcp消息,最后一台使用winsock2发送upd数据报。

我想知道我是否可以通过使用线程(OpenMP 或 boost::threads)来模拟 recvfrom(),以便 2 个线程同时从同一个端口上的同一个套接字监听。

我在 windows7 上使用 VC++ 2010。

感谢您的帮助。

4

2 回答 2

8

是的,套接字是线程安全的,但是你必须小心。一种常见的模式(当使用阻塞 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 线程安全吗?

于 2012-12-21T10:11:13.043 回答
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 请求,其他线程进行处理。

于 2012-12-21T02:48:12.897 回答