Java 检测TCP/IP数据包丢失
我通过套接字代码进行tcp通信,如: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
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])
在系统之间传输数据时,数据包可能会被丢弃,原因有两个:
- 高网络利用率和由此造成的拥塞
- 网络硬件或连接器故障
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对应用程序消息一无所知。是的,但我的疑问是,例外在哪里/