当前位置: 首页 > 面试题库 >

在多个线程的同一TCP套接字上发出阻塞write()调用是否安全?

苏嘉志
2023-03-14
问题内容

假设我有两个线程,T1和T2。

线程T1在TCP套接字S上进行阻塞的write()调用,以发送较大的字节B1缓冲区。字节B1的缓冲区很大,以致(a)写调用块和(b)TCP必须使用多个段来发送缓冲区。

线程T2还在同一TCP套接字S上进行了阻塞的write()调用,以发送字节B2的其他一些大缓冲区。

我的问题是这样的:

UNIX上的TCP实现是否保证B1的所有字节先于B2的所有字节发送(反之亦然)?

或者TCP可以交织B1和B2的内容(例如,TCP发送一个包含B1数据的段,然后发送一个具有B2数据的段,然后又发送一个具有B1数据的段)。

PS-我知道这样做不是一个好主意。我正在尝试确定一些我未编写的代码是否正确。


问题答案:

尝试

TL; DR: 出于编写和调试代码的目的,假定原子性是安全的,除非您的目标是生命支持系统。

如果tcp套接字上的send(2)(与相同write(2))不是原子的,那将总是不好的。从来没有充分的理由实现非原子写入。Unix和Windows的所有版本都试图保持原子写操作,但是显然很少提供保证。

Linux 通常 被称为 “通常”
1.做到这一点,但即使在最近的内核中,它也存在错误。它确实尝试锁定套接字,但是在某些情况下,内存分配可能会失败,并且写入将被拆分。有关详细信息,请参阅sendmsg上的此IBM博客条目。
[链接已修复。]

根据那些测试,只有AIX和Solaris完全通过了线程压力测试。甚至不知道那些系统是否有根本没有发现的故障案例。

1. TL; DR:几乎总是,即,除非存在某些错误,否则总是这样。



 类似资料:
  • 我正在编写一个需要向连接的远程主机发送数据的tcp服务器。我更希望套接字发送呼叫永远不要阻塞。为了方便起见,我使用了Socket。选择以标识可写套接字并使用Socket.Send写入这些套接字。插座。选择msdn文章状态: 如果您已经建立了连接,可写性意味着所有发送操作都将成功而不会阻塞。 我担心远程套接字没有主动耗尽缓冲区的情况,所述缓冲区填充,并且 tcp 推回我的服务器套接字。在这种情况下,

  • 问题内容: 为什么有人会喜欢阻止写而不是非阻止写?我的理解是,仅当您想确保写方法返回后,另一端获得了TCP数据包时,才希望阻止写操作,但是我什至不知道这是可能的。您将必须刷新,而刷新则必须刷新 底层操作系统的写套接字缓冲区 。那么,无阻塞套接字写是否有任何缺点?就性能而言,拥有较大的底层写套接字是否会缓冲一个不好的主意?我的理解是,底层套接字写缓冲区越小,当底层套接字缓冲区已满且isWritabl

  • 问题内容: 在Linux中,如果我们从一个线程调用阻塞并从另一个线程关闭同一个套接字,则不会退出。 为什么? 问题答案: 检查是否已关闭套接字的所有文件描述符。如果在“远程”端有任何打开的端口(假设这是您尝试关闭的端口),则“ 对等方尚未执行有序的关闭 ”。 如果仍然不起作用,请在远端调用,无论引用计数如何,都将关闭套接字。

  • 另外,除了调用recv函数后检查WSAGetLastError的值之外,是否还有其他方法可以使用TCP套接字库检测网络断开? 多谢!

  • 下面是我用来将套接字设置为非阻塞的代码: 你知道我做错了什么吗?(它在我的Windows构建中运行良好,使用: