检测TCP / IP丢包

时间:2014-07-01 17:49:04

标签: java sockets networking tcp

我通过socket代码进行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])。1

  

在系统之间传输数据时可以删除数据包,原因有两个:

  • 网络利用率高且导致拥塞
  • 网络硬件或连接器出现故障
  

TCP旨在能够在网络上丢弃数据包时做出反应。当数据包成功传送到目的地时,目标系统会将确认消息发送回源系统。如果在某个时间间隔内未收到此确认,则可能是因为目标系统从未收到过该数据包,或者因为包含确认的数据包本身已丢失。在任何一种情况下,如果源系统在给定时间内未收到确认,则源系统假定目标系统从未收到消息并重新发送。很容易看出,如果网络性能较差,数据包首先会丢失,而这些重传消息的负载增加只会进一步增加网络负载,这意味着会丢失更多的数据包。此行为可能导致在网络上快速创建紧急情况。

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

任何帮助?

3 个答案:

答案 0 :(得分:4)

  

TCP旨在能够在网络上丢弃数据包时作出反应。

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

TCP有一些功能可以为您完成一些工作,但您对它们的局限性感到好奇(许多人认为TCP是一种有保障的传送协议,没有上下文)。

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中的子类)将涵盖您描述的级别的错误情况:如果您获得一个,则采用重试策略(取决于应用程序及其用户的内容)意在做)。依赖于超时(不要将套接字永远设置为阻塞)。

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

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

编码您需要的内容。如果您需要确认,请实施它们。如果您希望发件人知道收件人获得了信息,那么让收件人发送某种确认。

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

不要试图让TCP做任何其他事情。不要试图教授TCP"你的协议。

相关问题