从多个线程在同一套接字上发布多个wssend

post many wsasend on the same socket from multiple threads

本文关键字:套接字 布多个 wssend 线程      更新时间:2023-10-16

(问题复制自msdn论坛)

MSDN这样说:

如果您正在使用I/O完成端口,请注意对WSASend的调用也是缓冲区的顺序已填充。不应在同一套接字上调用WSASend同时从不同的线程,因为这可能导致不可预测的缓冲顺序。

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

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

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

似乎实际上对WSASend()的调用不是线程安全的,如果您打算从同一连接上的多个线程调用WSASend),那么您应该同步,以便在任何给定点上只有一个线程真正调用API(即,在WSASend()调用周围保持每个连接的锁)。有关详细信息,请参阅此问题和随附的测试代码:TCP/IP IOCP接收到的数据有时已损坏-有关更详细的解释,请参阅Windows上的Visual C++和此博客条目。

还要注意,如果使用来自多个线程的多个WSASend()调用发送不同的应用程序级消息,则会出现问题,因为在将数据写入TCP流之前,多个调用可能会混合在一起。

所以,

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

来自5个不同线程的AA、BB、CC、DD、EE等,则您将无法获得包含的流

ABCCDDBAEE

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

如果您的线程使用多个send调用发送消息,例如三个send,那么来自线程1的A1A2A3将形成一个应用程序级消息。然后所有的赌注都取消了,因为你最终可能会得到

A1B1A2A3B2B3等。

如果以后需要这样做,您将需要在所有WSASend调用周围使用某种锁,以便将多个发送分组为单个应用程序级原子发送,或者您应该为单个WSASend呼叫使用多个WSABUF,以将多个写入集合到一个调用中。