c—在对等方关闭的tcp套接字上写入

ef1yzkbh  于 2021-06-09  发布在  Redis
关注(0)|答案(3)|浏览(311)

我有一个客户机-服务器应用程序,其中每一方通过tcp套接字与另一方通信。
我正确地建立了连接,然后在客户端将任何数据写入套接字之前使服务器崩溃。
我看到的是 write() 尝试(客户端)成功,它返回实际写入的字节数,而下面的返回(如我所料) -1 (接收a) SIGPIPE )以及 errno=EPIPE .
为什么是第一个 write() 即使套接字已关闭,也会成功吗?
有时也要编辑以下内容 write() 有一个积极的回报值,好像一切顺利。

bbuxkriu

bbuxkriu1#

这与tcp/ip的工作方式有关,可以粗略地描述为两个基本上独立的半连接。当您关闭服务器上的套接字时,客户端将被告知它将不会从服务器接收更多数据 C<-S 半连接,醒来 read() 立即,但不是关于 C->S 方向。它只有在尝试发送一些数据之后,才会收到重置连接的回复。我推荐tcp/ip指南以了解更多详细信息。
为什么有时候你可以 write() 两次是你写得比往返时间快,可以挤出一秒钟 write() 在第一个答复之前。

vmjh9lq9

vmjh9lq92#

你不知道 write() 手段。这并不意味着“同行得到了数据并承认了它”。相反,它的意思是,“我缓冲了这么多字节发送给对等方,它们现在是我的责任,所以你可以忘记它们(我没有任何未决的错误)”。
也就是说,如果tcp堆栈接受写入并返回n个字节,那并不意味着它们已经被写入,只是排队等待写入。在堆栈放弃并向您返回错误之前,可能需要一段时间,可能是在它开始发送网络流量后的30秒。在此期间,你可以打几个电话给 write() 成功地将要发送的数据排队(如果对等机消失,写错误将在c.30秒内返回,或者如果可以联系对等机并直接发送rst数据包以指示连接已断开,则立即返回。)

qncylg1j

qncylg1j3#

我正在使用以下方法检测服务器断开连接的情况:
在套接字上获得select()超时后(虽然应该没有收到任何内容),系统(“ping-c1-w1服务器”);'命令已激活。如果服务器已启动并且只是滞后,ping命令将在0.1秒内返回。否则(服务器关闭),ping命令将在1秒后返回。

相关问题