connect reset 與connect reset by peer 原因分析

     在項目組經常遇到TCP連接的問題,一直是遇到了網上查資料,沒有自己總結,感覺對這兩種錯都是模模糊糊,正好,今天又有個現場遇到此種問題需要我幫忙分析解決。通過查閱各種資料,算是比之前理解更加深刻。
     connect reset:原因是因客戶方已經把TCP連接斷開了,服務方還在往socket中寫數據。要重現connect reset  需要滿足條件:客戶端代碼中代碼要增加socket.setSoLinger(true, 0);查看java api,此句只對調用socket.close()有用,其作用就是當客戶端調用socket.close()會像服務端發送reset信號,如果服務端再對此連接進行讀、寫操作時,服務端就會報connection reset的異常。
connect reset by peer :此異常常見與服務端處理異常退出時,客戶端還在往socket裏面寫數據。前提條件也是:服務端代碼也設置了socket.setSoLinger(true, 0);
下面是驗證代碼

客戶端代碼:
package com.test.client;

import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Client {
private static int port = 9999;
private static String host = “127.0.0.1”;
public static SimpleDateFormat sdf = new SimpleDateFormat(“yy-MM-dd HH:mm:ss.SSS”);

public static void main(String[] args) throws Exception {
    Socket socket = new Socket();
    socket.setSoLinger(true, 0);

// CASE 3 😕/ socket.setSoLinger(true, 1);
SocketAddress address = new InetSocketAddress(Client.host, Client.port);
socket.connect(address);
OutputStream output = socket.getOutputStream();
StringBuilder strB = new StringBuilder();
for (int i = 0;
i < 10;
i++) {
strB.append(“H”);
}
byte[] request = strB.toString().getBytes(“utf-8”);
System.out.println("Client before write : " + sdf.format(new Date()));
output.write(request);
System.out.println("Client after write : " + sdf.format(new Date()));
socket.close();
System.out.println("Client after close : " + sdf.format(new Date()));
}
}

服務端代碼:
package com.test.server;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Server {
private static int queueSize = 10;
private static int port = 9999;
public static SimpleDateFormat sdf = new SimpleDateFormat(“yy-MM-dd HH:mm:ss.SSS”);

public static void main(String[] args) throws Exception {
    ServerSocket serverSocket = new ServerSocket();
    serverSocket.setReuseAddress(true);
    serverSocket.setReceiveBufferSize(128 * 1024);
    serverSocket.bind(new InetSocketAddress(Server.port), Server.queueSize);
    Socket socket = null;
    while (true) {
        socket = serverSocket.accept();

// socket.setSoLinger(true,0);
InputStream input = socket.getInputStream();
while(input.read() !=-1){
throw new Exception();
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = -1;
Thread.sleep(10 * 1000);
System.out.println("Server before read : " + sdf.format(new Date()));
while ((length = input.read(buffer)) != -1) {
output.write(buffer, 0, length);
}
System.out.println("Server after read : " + sdf.format(new Date()));
String req = new String(output.toByteArray(), “utf-8”);
System.out.println(req.length());
socket.close();
}
}
}
經過此次實際驗證,詳細對此兩個異常有更深刻的理解。後續遇到類似問題,思路會清晰很多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章