我收到一个java.net.SocketException:连接重置错误

时间:2013-12-03 00:52:07

标签: java multithreading

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;

public class Server {
    // ArrayList<PrintWriter> writers; // hold a list of current connections
    Set<Socket> sockets = new HashSet<Socket>();
    private ServerSocket serverSocket;
    private Socket sock;
    private static SimpleDateFormat date = new SimpleDateFormat(
            "dd/mm/yyyy hh:mm:ss");
    private static Calendar cal = Calendar.getInstance();

    public static void main(String[] args) {
        new Server().go();
    }

    public void go() {
        try {
            // setup port listener
            // add connections to arraylist
            // setup in and out streams
            System.out.println("waiting connetion");
            serverSocket = new ServerSocket(8999);
            // writers = new ArrayList<PrintWriter>();

            while (true) {
                sock = serverSocket.accept();
                sockets.add(sock);
                // PrintWriter writer = new PrintWriter(
                // sock.getOutputStream());
                // writers.add(writer);
                Thread t = new Thread(new ClientHandler(sock));
                t.start();
                System.out.println("connected");
            }
        } catch (IOException ex) {
            ex.printStackTrace();
            System.out.println("fail setup network");

        } finally {
            System.out.println("finally");

        }
    }

    class ClientHandler implements Runnable {
        private BufferedReader in;

        public ClientHandler(Socket sock) {
            // setup a client connection
            try {
                in = new BufferedReader(new InputStreamReader(
                        sock.getInputStream()));
            } catch (IOException e) {
                e.printStackTrace();

                System.out.println("fail classhandler");
            }
        }

        @Override
        public void run() {
            // receive and relay messages back to clients
            String message;
            try {
                while ((message = in.readLine()) != null) {
                    shout(message);
                    System.out.println("client says : "
                            + date.format(cal.getTime()) + message);
                }
            } catch (IOException ex) {
                try {
                    System.out.println("closing");
                    sock.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                sockets.remove(sock);
                System.out.println(sockets);
                ex.printStackTrace();
                System.out.println("fail read message");

            }
        }

        public synchronized void shout(String message) {
            // send message to all clients
            // for (PrintWriter writer : writers) {
            // writer.println(date.format(cal.getTime()) + " " + message
            // + "\n");
            // writer.flush();
            // }
            for (Socket sock : sockets) {
                try {
                    PrintWriter writer = new PrintWriter(sock.getOutputStream());
                    writer.println(date.format(cal.getTime()) + " " + message
                            + "\n");
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

        }

    }

}

=============================================== ======

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;

    public class Client {

        private JTextArea tArea;
        private BufferedReader in;
        private Socket sock;
        private PrintWriter out;

        public static void main(String[] args) {
            new Client().go();
        }

        public void go() {
            JFrame frame = new JFrame("Chat Client");
            final JTextField tField = new JTextField(25);
            tArea = new JTextArea(30, 20);
            JButton button = new JButton("send");
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    sendMessage(tField.getText());
                    tField.setText("");
                }
            });
            frame.setSize(300, 500);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(tArea, BorderLayout.NORTH);
            frame.add(tField, BorderLayout.CENTER);
            frame.add(button, BorderLayout.EAST);
            frame.pack();
            setupNetwork();
            Thread t = new Thread(new IncomingReader());
            t.start();
        }

        public void setupNetwork() {
            try {
                sock = new Socket("localhost", 8999);
                in = new BufferedReader(
                        new InputStreamReader(sock.getInputStream()));
                out = new PrintWriter(sock.getOutputStream());
            } catch (IOException ex) {
                ex.printStackTrace();
                System.out.println("fail networking");


}
    }

    class IncomingReader implements Runnable {
        public void run() {
            //receive messages from server
            try {
                String message = null;
                while ((message = in.readLine()) != null) {
                    tArea.append(message + "\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("fail incoming reader");

            }
        }
    }

    public void sendMessage(String message) {
        try {
            out.println(message);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("fail send message");
        }
    }
}

当我关闭一个客户端时,我收到了这个错误,我尝试了关闭我的连接,但最终我不知道如何摆脱这个错误:

fail read message
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 Server$ClassHandler.run(Server.java:63)
    at java.lang.Thread.run(Unknown Source)

我知道它,因为我正在关闭一个连接,但它一直在抛出这个错误而且它很烦人,即使它没有破坏我的服务器。

4 个答案:

答案 0 :(得分:4)

通常的原因是您已写入已被另一端关闭的连接。换句话说,应用程序协议错误。

这里的具体问题是,当您从服务器中的null获得readLine()时,您应该关闭该套接字并从编写器数组中删除相应的Writer以进行呼叫。

答案 1 :(得分:2)

那是因为你应该在客户端上完成它后正确关闭套接字。我不是SWING大师,但看起来像WindowListener就是你所需要的。只需在主窗口关闭时关闭连接。

编辑:关闭TCP套接字时,需要完成一些工作:http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination。当你关闭程序时,这不会发生。操作系统将为您关闭连接并释放所有相关资源,但服务器不会收到关于客户端关闭连接的通知。

编辑2:示范 服务器:

public class Server {
    public static void main(String args[]) {
          try {
              System.out.println("waiting connetion");
              ServerSocket serverSocket = new ServerSocket(8999);
              while (true) {
                  Socket clientSocket = serverSocket.accept();
                  System.out.println("Connected");
                  Reader reader = new InputStreamReader(
                          clientSocket.getInputStream());
                  reader.read(); // wait for input
                  System.out.println("No exception");
              }
          } catch (IOException ex) {
              System.out.println("Exception");
              ex.printStackTrace();
          }
    }
}

客户端:

public class Client {
    public static void main(String args[]) throws Exception {
         Socket sock = new Socket("localhost", 8999);
         System.out.println("Press 1 to close gracefully, any other nuber otherwise");
         Scanner sc = new Scanner(System.in);
         if (sc.nextInt() ==1 ) {
             sock.close();
         } else {
             //do nothing
         }
    }
}

答案 2 :(得分:0)

socketname.close()方法放在您的客户端中...问题是客户端在服务器可以从中读取流之前完成了...

答案 3 :(得分:-1)

告诉java代码应该通过代理路由所有HTTP请求,请使用以下代码段:

System.setProperty("http.proxyHost", "proxyHost");
System.setProperty("http.proxyPort", "proxyPort");
Authenticator authenticator = new Authenticator() {
     public PasswordAuthentication getPasswordAuthentication() {
    return (new PasswordAuthentication("USERNAME","PASSWORD".toCharArray()));
    }
};
Authenticator.setDefault(authenticator);

System.setProperty设置代理主机和端口。 Authenticator应该是您的公司用户名和密码。这应该现在有效。