udp 超时重传 java_UDP实现简单的超时重传

本文介绍了如何在Linux下利用阻塞式I/O模式和alarm函数,结合sigaction,为UDP实现简单的超时重传机制,确保两个程序间的通信可靠性。通过设置SO_RCVTIMEO和SO_SNDTIMEO,或者使用alarm和sigaction来处理超时,避免因数据包丢失导致的程序阻塞。
摘要由CSDN通过智能技术生成

众所周知~UDP是一个无连接协议,因此靠它来传输的话是不可靠的,即使是数据包丢失也不会报错。但是,在编写Linux上的socket程序时,却可以用简单的方法,在应用层实现超时重传,让UDP可靠一些。(这次说的方法最好用于两个程序间通信——也许只能用于两台机器通信)首先~我介绍一下Linux下,I/O操作的阻塞模式:

在Linux下,I/O操作有四种模式,分别为:阻塞式I/O,非阻塞式I/O,多路复用I/O,一击信号驱动I/O,这次需要用到的是阻塞式I/O。阻塞式I/O是最简单,最常用但也是效率最低的一个。在默认模式下,所有的套接字都是阻塞模式,即:当用户调用这些函数时,函数将一直阻塞下去,直至有某个事件发生。具体事件依函数而定,比如:调用读函数,由于缓存中还没有数据,而使得读函数发生读阻塞;同理,也可能在调用写函数的时候发生写阻塞;除此之外,还有调accept函数的时候,由于没有客户连接服务器,使得其发生阻塞;调用connect函数时,由于三次握手没有结束,使得其发生阻塞等等。也就是说~在没有特定事件发生的情况下,函数将什么也不干而等待事件发生,事件发生后则继续执行程序。而有些时候,由于某些原因,会使得函数永远处于阻塞模式(比如:客户用UDP给服务器传送数据的数据丢失,使得服务器端的recvfrom函数始终处于阻塞模式)这就需要调用某些函数使这些函数不再阻塞,具体方法有:

1、使用信号:比如调用alarm函数

2、在套接字上设置SO_RCV

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中,可以使用 `DatagramSocket` 类来实现 UDP 传输。可以通过使用 `setSoTimeout()` 方法来设置超时时间,一旦超时时间达到,就会抛出 `SocketTimeoutException` 异常。 如果需要实现超时重传机制,可以在捕获 `SocketTimeoutException` 异常后,重新发送数据包。可以设置一个计数器来记录发送次数,达到一定次数后,可以认为数据包丢失,停止重传。 下面是一个简单UDP 超时重传示例: ```java // 创建 DatagramSocket 对象 DatagramSocket socket = new DatagramSocket(); // 创建 DatagramPacket 对象,将数据打包发送 byte[] data = "Hello, World!".getBytes(); InetAddress address = InetAddress.getByName("localhost"); int port = 8080; DatagramPacket packet = new DatagramPacket(data, data.length, address, port); // 设置超时时间和重传次数 int timeout = 1000; // 超时时间为 1 秒 int maxTries = 3; // 最大重传次数为 3 次 // 发送数据包 int tries = 0; boolean receivedResponse = false; do { socket.send(packet); // 发送数据包 try { byte[] buffer = new byte[1024]; DatagramPacket response = new DatagramPacket(buffer, buffer.length); socket.setSoTimeout(timeout); // 设置超时时间 socket.receive(response); // 接收响应 receivedResponse = true; } catch (SocketTimeoutException e) { tries++; System.out.println("Timeout, " + (maxTries - tries) + " more tries..."); } } while (!receivedResponse && tries < maxTries); socket.close(); // 关闭 socket ``` 在上面的代码中,我们通过 `setSoTimeout()` 方法设置了超时时间为 1 秒,最大重传次数为 3 次。在发送数据包后,我们使用一个循环来等待响应。如果超时时间到达,就会捕获 `SocketTimeoutException` 异常,并重新发送数据包。如果达到最大重传次数,就会退出循环。如果接收到响应,就会将 `receivedResponse` 标记为 true,退出循环。最后,我们关闭 socket。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值