Java - Socketexception:连接重置

时间:2015-04-03 16:15:35

标签: java

我目前正在开展一个小型聊天程序。我遇到问题的两个类是包含clientide和socket的服务器端的类。我希望客户端读取服务器发送的行。我收到这个错误:

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
    at sun.nio.cs.StreamDecoder.read(Unknown Source)
    at java.io.InputStreamReader.read(Unknown Source)
    at java.io.BufferedReader.fill(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at MainPanel.run(MainPanel.java:121)
    at java.lang.Thread.run(Unknown Source)

我读到,这种情况发生了,因为套接字连接在服务器端关闭,但我无法看到代码中发生的情况。有人可以解释,为什么会发生这种情况或如何解决它?

客户代码邮箱:

try {
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        while(true) {
            chatArea.append(br.readLine() + "\n"); //line 121
        }
    } catch(Exception ex) { ex.printStackTrace(); }

服务器的代码段:

while(true) {
        System.out.println("Waiting for someone to connect.");
        Socket currentSocket = serverSocket.accept();
        System.out.println("Someone connected.");

        sockets.add(currentSocket);

        new Thread(new Runnable() {

            public void run() {

                try {
                    while(true) {
                        BufferedReader br = new BufferedReader(new InputStreamReader(currentSocket.getInputStream()));
                        String input = br.readLine();
                        for(Socket socket : sockets) {
                            PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
                            pw.println(input);
                        }
                    }
                } catch(Exception ex) {
                    sockets.remove(currentSocket);
                    System.out.println("One connection lost.");
                }
            }
        }).start();
    }

1 个答案:

答案 0 :(得分:0)

当服务器应用程序终止时,绑定到客户端Socket对象的TCP会话抛出SocketException,这是完全正常的。您的方案没有任何问题。您需要做的是您必须在客户端和服务器端都处理SocketException。客户端或服务器可以终止TCP会话。在客户端,您可能有一个可能尝试重新初始化TCP会话的逻辑,而在服务器端,您可以清除与TCP会话相关的对象。

样本跑步者类:

public class TCPProcessor implements Runnable {
        private Socket s;
        private Thread th;

        public TCPProcessor(Socket s) {
            this.s = s;
            th = new Thread(this);
            tcpProcessors.add(this);
            th.start();
        }

        public void stop() {
            try {
                s.close();
            } catch (Exception e) {
                LOGGER.trace("socket couldn't be closed");
            }
            th.interrupt();
        }

        @Override
        public void run() {
            Request r = null;
            try {
                ObjectInputStream inFromClient = new ObjectInputStream(s.getInputStream());
                ObjectOutputStream outToClient = new ObjectOutputStream(s.getOutputStream());
                while (isStarted()) {
                    final Object receivedObject = inFromClient.readObject();
                    // LOGGER.debug("Receiving "
                    // + ((Request) receivedObject).getRequestType() + " "
                    // + receivedObject);
                    r = (Request) receivedObject;
                    processId.set(r.getProcessId());
                    Response rs = new Response();
                    rs.setRequest(r);
                    rs.setServerFrom(GoldenNodeServer.this);
                    if (getOperationBase() != null) {
                        try {
                            Object s = ReflectionUtils.callMethod(getOperationBase(), r.getMethod(), r.getParams());
                            rs.setReturnValue(s);
                        } catch (Exception e) {
                            rs.setReturnValue(e);
                        }
                        outToClient.writeObject(rs);
                    } else {
                        rs.setReturnValue(new NoClientProxySetException());
                    }
                }
            } catch (EOFException e) {
                // LOGGER.trace("eof occured");
            } catch (SocketException e) {
                if (e.toString().contains("Socket closed") || e.toString().contains("Connection reset")
                        || e.toString().contains("Broken pipe")) {
                } else {
                    stop();
                    LOGGER.error("Error occured" + (r == null ? "" : " while processing " + r) + " ", e.toString());
                }
            } catch (IOException | ClassNotFoundException e) {
                stop();
                LOGGER.error("Error occured" + (r == null ? "" : " while processing " + r) + " ", e.toString());
            } finally {
                tcpProcessors.remove(this);
            }
        }
    }