Socket 编程中,如何处理网络异常和断网情况?

在Socket编程中,经常会遇到网络异常和断网情况,主要包括:

  1. 连接超时:客户端连接服务端超过一定时间未成功,视为连接超时。
  2. 读取超时:客户端读取服务端数据超过一定时间无响应,视为读取超时。
  3. 连接中断:网络出现故障导致连接中断,客户端和服务端无法通信。
  4. 服务端宕机:服务端系统出现故障导致服务不可用。

处理网络异常和断网情况的主要方法有:

  1. 设置超时:为Socket设置连接超时时间和读取超时时间,超时后重新连接。
  2. 心跳检测:定期检测连接是否正常,超过一定时间无心跳则视为断网并重新连接。
  3. 重连机制:出现网络异常后,客户端不断尝试重新连接服务端,连接成功后恢复通信。
  4. 断线重传:客户端对已发送但未确认的数据包进行重传,确保服务端接收完整数据。
  5. 超时重传:在一定时间内未接收到确认信息,客户端主动重传数据包。

代码示例:

// 客户端  
Socket socket;
boolean connected = false;

while (!connected) {
    try {
        socket = new Socket("127.0.0.1", 8000);
        socket.setSoTimeout(5000);  // 设置超时时间
        connected = true;
    } catch (IOException e) {
        // 连接超时,继续尝试连接
    }
}

OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();

int heartBeatInterval = 2000;   // 心跳间隔  
long lastHeartBeat = System.currentTimeMillis();
while (connected) {
    if (System.currentTimeMillis() - lastHeartBeat > heartBeatInterval * 2) {
        // 两次心跳间隔超过2倍,视为断网并重连
        connected = false; 
        continue;
    }

    // 发送心跳和数据,读取确认和数据  
    // ...

    if (in.read() == -1)  // 读取超时,重传未确认数据
        retransmitPacket();  
}