关闭套接字连接

时间:2012-01-20 12:21:41

标签: java multithreading sockets client-server

我有两个运行聊天程序的线程,一个是服务器,另一个是客户端,一切正常,直到我点击退出按钮。

因为单击Quit按钮的线程的Socket被异步关闭而另一个套接字试图读取数据,所以/ living线程中的读取套接字被闭包干扰并触发错误mssg,同时exepcted到正确关闭自己的插座并静静地死。

我需要建议过来......

这是我得到的错误mssg:

java.net.SocketException: socket closed
    at java.net.SocketInputStream.socketRead0(Native Method)
    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 chatSockets.ChatClient.run(ChatClient.java:56)
    at java.lang.Thread.run(Unknown Source)

那就是代码:

public void run() {
    try {
        if (type==Type.CLIENT) {
            socket = new Socket(HOST, PORT);
        } else {
            ServerSocket ss = new ServerSocket(PORT);
            socket = ss.accept();
        }
        out = new PrintWriter(socket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(
                socket.getInputStream()));

        while (!socket.isInputShutdown()) {
            chat.append(in.readLine()+"\n");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void actionPerformed(ActionEvent e) {
    String s = name + " : " + chat.getMssg();
    JButton src=(JButton)e.getSource();
    if (src.getText()=="Quit") {
        out.close();
        try {
            in.close();
            socket.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        System.exit(0);
    }
    else {
        out.println(s);
        chat.append(s + "\n");
        chat.clearPanel();
    }

}

3 个答案:

答案 0 :(得分:3)

这是预期的行为。只需处理catch块中另一端的套接字关闭并继续执行。

来自javadoc:

public String readLine()
                throws IOException

Read a line of text. A line is considered to be terminated by any one of a 
line feed ('\n'), a carriage return ('\r'), or a carriage return followed 
immediately by a linefeed.

Returns:
    A String containing the contents of the line, not including any 
    line-termination characters, or null if the end of the stream has been 
    reached 
Throws:
    IOException - If an I/O error occurs

所以你有两个选择:要么依赖于当另一端关闭套接字时抛出IOException并在catch块中进行清理,或者如果你想要一个干净的关闭方式发送一个特殊的“停止令牌”到另一个线程,表示你正在退出,它应该关闭它的端口。

答案 1 :(得分:0)

服务器启动后,您确定客户端正在运行吗?

如果您尝试在服务器套接字之前创建客户端套接字连接。它不会打开插座。

答案 2 :(得分:0)

当服务器未启动时,尝试在客户端捕获异常。