gpt4 book ai didi

当服务器被杀死时,Ruby TCPSocket 不会注意到它

转载 作者:数据小太阳 更新时间:2023-10-29 07:31:16 28 4
gpt4 key购买 nike

我有这个连接到 TCP 服务器(即 netcat)的 ruby​​ 代码。它循环 20 次,并发送“ABCD”。如果我杀死 netcat,则需要两次循环迭代才能触发异常。在 netcat 被杀死后的第一个循环中,没有触发异常,并且“发送”报告已正确写入 5 个字节...这最终不是真的,因为服务器当然没有收到它们。

有没有办法解决这个问题?现在我正在丢失数据:因为我认为它已正确传输,所以我不会重播它。

#!/usr/bin/env ruby
require 'rubygems'
require 'socket'

sock = TCPSocket.new('192.168.0.10', 5443)
sock.sync = true

20.times do
sleep 2
begin
count = sock.write("ABCD ")
puts "Wrote #{count} bytes"
rescue Exception => myException
puts "Exception rescued : #{myException}"
end
end

最佳答案

当您发送数据时,您的阻塞调用将在数据写入 TCP 输出缓冲区时返回。它只会在缓冲区已满时阻塞,等待服务器确认收到之前发送的数据。

一旦此数据进入缓冲区,网络驱动程序就会尝试发送数据。如果连接丢失,在第二次尝试写入时,您的应用程序会发现连接已断开。

另外,连接如何关闭?服务器是否主动关闭连接?在这种情况下,客户端套接字将在其下一次套接字调用时得到通知。或者它崩溃了?或者可能存在网络故障,这意味着您无法再进行通信。

只有当您尝试通过套接字发送或接收数据时,才会发现断开的连接。这与主动关闭连接不同。如果不对它做任何事情,您根本无法确定连接是否仍然存在。

因此尝试在写入后执行 sock.recv(0) - 如果套接字失败,这将引发“Errno::ECONNRESET:连接由对等方重置 - recvfrom(2)”。您也可以尝试 sock.sendmsg "", 0(不是 sock.write 或 sock.send),这将报告一个 "Errno::EPIPE: Broken pipe - sendmsg(2 )”。

即使您拿到了 TCP 数据包并得到数据已在另一端收到的确认,仍然不能保证服务器会处理此数据 - 它可能在其输入缓冲区中但尚未处理.

所有这些可能有助于更早地识别断开的连接,但仍然不能保证数据已被服务器和处理接收。知道应用程序已处理您的消息的唯一可靠方法是使用应用程序级响应。

关于当服务器被杀死时,Ruby TCPSocket 不会注意到它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2530652/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com