【发布时间】:2014-11-20 17:18:54
【问题描述】:
(问题复制自msdn论坛)
MSDN 是这样说的:
如果您使用 I/O 完成端口,请注意 对 WSASend 的调用也是缓冲区的顺序 人口稠密。不应在同一个套接字上调用 WSASend 同时来自不同的线程,因为它可能导致 不可预知的缓冲顺序。
好的...但是如果我不关心这个订单并且也不关心订单我会在另一边收到它...那我可以使用它吗?从多个线程调用 WSASend 是否安全?包裹是否会按照我传递的方式交付(可能订购方式不同,但完整)??
例如-> 我发送 [12a]、[34b]、[11c] 和 [223d] ...([] 标记我在一次呼叫中传递给 WSASend 的单元)然后我会收到例如34b、11c、12a、223d ?或者它会崩溃吗?或者我能收到像 2a, 34b, 7a, 5c, ...
所以,也许问题应该是 -> 它是线程安全的吗?它是原子的吗? (我说的是与 IOCP 一起使用的 WSASend,所以重叠)
【问题讨论】:
-
IIRC 是的,你可以这样做。这样的调用是线程安全的,但不是 TCP 安全的:)
-
想一想——WSARecv() 调用同一套接字返回的两个缓冲区并由两个不同的池线程处理是不寻常的,但并非不可能。处理完缓冲区数据后,这些线程可能会发出 WSASend 调用以“同时”将回复发送到一个套接字。所以是的,它们必须是线程安全的。
-
我的场景更可能使用 UDP 协议,因为两个池线程获得需要回复的完整数据报的机会将高于 TCP。
-
@Martin James 感谢回复。你说的 TCP 安全是什么意思?在我的服务器(tcp)中,经常出现一种情况,当来自多个线程的同一个套接字上的许多 wsasend 被发布时(一个 wsasend - 一条短消息(最多 30 个字节),我也不关心缓冲区顺序,客户端也不关心)。
标签: c++ multithreading sockets send iocp