Connection reset 及 connection reset by peer

/ 后端 / 没有评论 / 66浏览

解释

1.服务器返回了“RST”时,如果此时客户端正在从Socket套接字的输出流中读数据则会提示Connection reset”;
2.服务器返回了“RST”时,如果此时客户端正在往Socket套接字的输入流中写数据则会提示“Connection reset by peer”。
3.该异常在客户端和服务器端均有可能发生,引起该异常的原因有两个,第一个就是如果一端的Socket被关闭(或主动关闭或者因为异常退出而引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。另一个是一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的。

原因

(1)例如当浏览器等客户端连接服务器发送报文之前关闭浏览器或其他原因未正常关闭;
(2)服务端使用网络工具如httpclient等,工具提供了连接池,当池中的连接不可用时,再进行读写都会报异常;但是工具提供了使用前检查机制以及重试机制,可以规避引发其他问题的产生;

模拟

linux操作

#新建一个百度的输入输出流文件描述符
exec 9<> /dev/tcp/www.baidu.com/80
#http协议get请求标准输出到百度的文件描述符
echo -e "GET / Http/1.0\n" 1>& 9
#获取百度返回的标准输入
cat 0<& 9
#以上可以长时间等待操作,可导致连接断开报错

使用java

先启动服务端监听端口;启动客户端,当执行到睡眠时关闭程序;服务端将报错;

server

 public static void main(String[] args) {
        new Thread(new SimpleServer()).start();
    }

    static class SimpleServer implements Runnable {
        // run() method for thread
        @Override
        public void run() {

            ServerSocket serverSocket = null;

            // Try block to check for exceptions
            try {
                serverSocket = new ServerSocket(3333);
                serverSocket.setSoTimeout(0);
                // Till condition holds true
                while (true) {
                    try {
                        Socket clientSocket = serverSocket.accept();

                        // Creating an object of
                        // BufferedReader class
                        BufferedReader inputReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

                        System.out.println("Client said :" + inputReader.readLine());
                    }
                    // Handling the exception
                    catch (SocketTimeoutException e) {
                        // Print the exception along with
                        // line number
                        e.printStackTrace();
                    }
                }
            }
            // Catch block to handle the exceptions
            catch (IOException e1) {
                // Display the line where exception occurs
                e1.printStackTrace();
            } finally {
                try {
                    if (serverSocket != null) {
                        serverSocket.close();
                    }
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }
        }
    }

client

   public static void main(String[] args) {
        new Thread(new SimpleClient()).start();
    }

    static class SimpleClient implements Runnable {
        // run() method for the thread
        @Override
        public void run() {
            // Initially assign null to our socket to be
            // used
            Socket socket = null;
            // Try block to e=check for exceptions
            try {
                socket = new Socket("localhost", 3333);
                // Creating an object of PrintWriter class
                PrintWriter outWriter = new PrintWriter(socket.getOutputStream(), true);
                // Display message
                System.out.println("Wait");

                // making thread to sleep for 1500
                // nanoseconds
                Thread.sleep(20000);
                // Display message
                outWriter.println("Hello Mr. Server!");
            }
            // Catch block to handle the exceptions
            // Catch block 1
            catch (SocketException e) {
                // Display the line number where exception
                // occurred using printStackTrace() method
                e.printStackTrace();
            }
            // Catch block 2
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            // Catch block 3
            catch (UnknownHostException e) {
                e.printStackTrace();
            }
            // Catch block 4
            catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    // If socket goes NULL
                    if (socket != null)
                        // Close the socket
                        socket.close();
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }
        }
    }