gpt4 book ai didi

java - 检测 TCP/IP 数据包丢失

转载 作者:可可西里 更新时间:2023-11-01 02:35:07 37 4
gpt4 key购买 nike

我通过如下套接字代码进行 tcp 通信:

public void openConnection() throws Exception
{
socket = new Socket();
InetAddress iNet = InetAddress.getByName("server");
InetSocketAddress sock = new InetSocketAddress(iNet, Integer.parseInt(port));
socket.connect(sock, 0);

out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}

发送方法为:

synchronized void send(String message)
{
try
{
out.println(message);
}
catch (Exception e)
{
throw new RuntimeException(this.getClass() + ": Error Sending Message: "
+ message, e);
}
}

我从网页上读到,TCP/IP 不保证数据包的传送,它会重试,但如果网络太忙,数据包可能会被丢弃([链接])。 1

Packets can be dropped when transferring data between systems for two key reasons:

  • 网络利用率高,导致拥堵
  • 网络硬件或连接器故障

TCP is designed to be able to react when packets are dropped on a network. When a packet is successfully delivered to its destination, the destination system sends an acknowledgement message back to the source system. If this acknowledgement is not received within a certain interval, that may be either because the destination system never received the packet or because the packet containing the acknowledgement was itself lost. In either case, if the acknowledgement is not received by the source system in the given time, the source system assumes that the destination system never received the message and retransmits it. It is easy to see that if the performance of the network is poor, packets are lost in the first place, and the increased load from these retransmit messages is only increasing the load on the network further, meaning that more packets will be lost. This behaviour can result in very quickly creating a critical situation on the network.

有什么方法可以检测到目的地是否成功接收到数据包,我不确定 out.println(message); 会抛出任何异常,因为这不是阻塞调用。它将消息放入缓冲区并返回让 TCP/IP 完成它的工作。

有什么帮助吗?

最佳答案

TCP is designed to be able to react when packets are dropped on a network.

正如您的引述所说,TCP 旨在自动响应您在本文中提到的事件。因此,您在此级别无需执行任何操作,因为这将由您正在使用的 TCP 实现处理(例如在操作系统中)。

TCP 的某些功能可以为您完成一些工作,但您有理由怀疑它们的局限性(许多人认为 TCP 是一种有保证的传送协议(protocol),没有上下文)。

有一个interesting discussion on the Linux Kernel Mailing List ("Re: Client receives TCP packets but does not ACK")关于这个。

在您的用例中,实际上,这意味着您应该将 TCP 连接视为每个方向的数据流(典型的错误是假设如果您从一端发送 n 个字节,您将读取 n在另一端读取单个缓冲区中的字节),并处理可能的异常。

正确处理 java.io.IOException(特别是 java.net 中的子类)将涵盖您所描述级别的错误情况:如果您得到一个,有重试策略(取决于应用程序及其用户打算做什么)。也依赖超时(不要将套接字设置为永远阻塞)。

应用程序协议(protocol)也可以设计为在收到命令或请求时发送自己的确认。

这是将职责分配给不同层的问题。 TCP 堆栈实现将处理您提到的丢包问题,如果无法自行修复,则会抛出错误/异常。它的职责是与远程 TCP 栈的通信。由于在大多数情况下您希望您的应用程序与远程应用程序对话,因此需要在此之上进行额外的确认。通常,需要设计应用程序协议(protocol)来处理这些情况。 (在某些情况下,您可以向上层数,具体取决于哪个实体负责处理请求/命令。)

关于java - 检测 TCP/IP 数据包丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24516418/

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