c++ - 从多个线程在同一个套接字上发布许多 wsasend

标签 c++ multithreading sockets send iocp

(问题是从msdn论坛复制过来的)

MSDN 是这样说的:

If you are using I/O completion ports, be aware that the order of calls made to WSASend is also the order in which the buffers are populated. WSASend should not be called on the same socket simultaneously from different threads, because it can result in an unpredictable buffer order.

好的...但是如果我不关心这个订单也不关心我会在另一边收到的订单...那么我可以使用它吗?从多个线程调用 WSASend 是否安全?包裹会按照我传递的方式交付吗(可能订购方式不同,但完整)??

例如-> 我发送 [12a]、[34b]、[11c] 和 [223d] ...([] 标记我在一次调用中传递给 WSASend 的单元)然后我会收到,例如34b、11c、12a、223d?或者它会崩溃吗?或者我可以收到诸如 2a、34b、7a、5c 之类的东西吗?

所以,也许问题应该是 -> 它是线程安全的吗?它是原子的吗? (我说的是与 IOCP 一起使用的 WSASend,所以重叠了)

最佳答案

似乎实际上对 WSASend() 的调用不是线程安全的,如果您打算从同一连接上的多个线程调用 WSASend(),那么您应该同步,以便在任何时候只有一个线程实际调用 API给定点(即在 WSASend() 调用周围保持每个连接锁)。有关详细信息,请参阅此问题和随附的测试代码:TCP/IP IOCP received data sometimes corrupt - Visual C++ on Windowsthis blog entry以获得更详细的解释。

另请注意,如果您使用来自多个线程的多个 WSASend() 调用发送不同的应用程序级消息,那么您会遇到一个问题,因为在数据写入 TCP 流之前多个调用可能会混合在一起。

所以,

如果您有 5 个线程发送“完整的 2 字节消息”,这样您就可以发送

来自 5 个不同线程的 AA、BB、CC、DD、EE 等,那么您将不会获得包含

ABCCDDBAEE

但您可以获得消息顺序的任意组合。

如果您的线程通过多个发送调用发送消息,例如三个发送,来自线程 1 的 A1 A2 A3 形成单个应用程序级消息。然后所有的赌注都关闭了,因为你最终可能会得到

TCP 流中的 A1B1A2A3B2B3 等。

如果您以后需要执行此操作,您将需要对所有 WSASend 调用进行某种锁定,以便您可以将多个发送分组为单个应用程序级原子发送,或者您应该为单个 WSASend 使用多个 WSABUF调用以将多个写入聚集到一个调用中。

关于c++ - 从多个线程在同一个套接字上发布许多 wsasend,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26046966/

相关文章:

C++正则表达式的简单使用

c++ - OpenCL Reduce 内核只返回一个值

c - 多线程等待的 `pthread_mutex_lock()` 唤醒顺序是什么?

java - 随机SocketException : Connection reset

.net - 如何避免由于 2x 反向代理网络中未关闭套接字而导致端口耗尽?

java - Android 套接字 : listening doesn't work through 4G

c++ - 为什么模板函数仅基于返回类型适用于 C++?

c++ - 简单的单链表复杂度查询

java - 使用多线程重绘paintComponent

ios - performSelectorInBackground 和 detachNewThreadSelector 是如何工作的?