假设我有两个线程,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构建中运行良好,使用: