Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检测TCP/IP数据包丢失_Java_Sockets_Networking_Tcp - Fatal编程技术网

Java 检测TCP/IP数据包丢失

Java 检测TCP/IP数据包丢失,java,sockets,networking,tcp,Java,Sockets,Networking,Tcp,我通过套接字代码进行tcp通信,如: public void openConnection() throws Exception { socket = new Socket(); InetAddress iNet = InetAddress.getByName("server"); InetSocketAddress sock = new InetSocketAddress(iNet, Integer.parseInt(port)); socket.connect(soc

我通过套接字代码进行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不能保证数据包的传输,它会重试,但如果网络太忙,数据包可能会被丢弃([link])

在系统之间传输数据时,数据包可能会被丢弃,原因有两个:

  • 高网络利用率和由此造成的拥塞
  • 网络硬件或连接器故障
TCP被设计成能够在网络上丢弃数据包时做出反应。当一个数据包成功地传送到它的目的地时,目的地系统向源系统发送一个确认消息。如果在某个间隔内未接收到该确认,这可能是因为目标系统从未接收到该分组,或者是因为包含该确认的分组本身丢失了。在任何一种情况下,如果源系统在给定时间内未收到确认,则源系统假定目标系统从未收到该消息并重新传输该消息。很容易看出,如果网络的性能较差,数据包首先会丢失,而这些重传消息增加的负载只会进一步增加网络上的负载,这意味着会丢失更多的数据包。这种行为会很快在网络上造成危急情况

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


有什么帮助吗?

TCP/IP不会丢弃数据包。TCP实现中的拥塞控制算法负责重传。假设有稳定的数据流被发送,接收器将确认它接收到的序列号返回给发送者。发送方可以使用确认来推断哪些数据包需要重新发送。发送方保留数据包,直到它们被确认


作为一个应用程序,除非TCP实现提供接收拥塞通知的机制,否则它所能做的最好的事情就是为事务何时可以完成建立一个超时。如果超时发生在事务完成之前,应用程序可能会声明网络过于拥挤,应用程序无法成功。

编写所需代码。如果您需要确认,请实现它们。如果你想让发送者知道接收者得到了信息,那么让接收者发送某种形式的确认

从应用程序的角度来看,TCP提供了一个双向字节流。您可以通过简单地指定用于传输所需信息的字节流来传输任何信息

不要试图让TCP做任何其他事情。不要试图“教TCP”您的协议

TCP被设计成能够在网络上丢弃数据包时做出反应

正如你的引文所说,TCP的设计目的是对你在本文中提到的事件自动做出反应。因此,在这个级别上您没有任何事情要做,因为这将由您正在使用的TCP实现来处理(例如,在操作系统中)

TCP有一些特性可以为您完成一些工作,但您有理由怀疑它们的局限性(许多人认为TCP是一种无上下文的有保证的交付协议)

关于这一点,有一个很好的解释

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

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

应用协议也可以设计成在接收命令或请求时发送它们自己的确认


这是一个将责任分配给不同层的问题。TCP堆栈实现将处理您提到的数据包丢失问题,如果无法自行修复,将抛出错误/异常。它的职责是与远程TCP堆栈通信。因为在大多数情况下,您希望您的应用程序与远程应用程序进行通信,所以需要在其上附加一个确认。通常,需要设计应用程序协议来处理这些情况。(在某些情况下,根据负责处理请求/命令的实体的不同,您可以上多个层。)

整个重传过程在不同的层中完成。您没有通过Java访问它的权限。这是为你做的。但是它能保证重新传输会发生并且成功吗?它不会失败吗?这是TCP为您准备的。它将继续重试(或多或少)。如果在一定时间后失败,您可能会收到超时错误。是的,关于该超时,我将在哪里获得该超时?在java或其他地方?它会传播到java,是的。查看
Socket
javadoc。我不是想教TCP任何东西,而是想学习TCP:你是。您已经创建了一条消息。您正在询问该消息何时超时。TCP不知道“消息”是什么(记住,您创建了这个“消息”)。您正在尝试将其设置为一个消息协议,它能够理解消息发生的情况。如果您需要确认消息或超时,则必须对其进行编码。TCP对应用程序消息一无所知。是的,但我的疑问是,例外在哪里/