Java 闭合插座连接

Java 闭合插座连接,java,multithreading,sockets,client-server,Java,Multithreading,Sockets,Client Server,我有两个线程运行一个聊天程序,一个是服务器,另一个是客户端,在我点击退出按钮之前一切正常 由于单击退出按钮的线程的套接字在另一个套接字尝试读取数据时异步关闭,因此/living线程中的读取套接字会受到关闭的干扰并触发错误mssg,同时EXEPC也会正确关闭自己的套接字并安静地死掉 我需要建议来解决这个问题 这是我得到的错误mssg: java.net.SocketException: socket closed at java.net.SocketInputStream.socketRe

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

由于单击退出按钮的线程的套接字在另一个套接字尝试读取数据时异步关闭,因此/living线程中的读取套接字会受到关闭的干扰并触发错误mssg,同时EXEPC也会正确关闭自己的套接字并安静地死掉

我需要建议来解决这个问题

这是我得到的错误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();
    }

}

您确定客户端在服务器启动后工作吗


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

服务器启动后,您确定客户端正在工作吗


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

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

从javadoc:


因此,这里有两个选项:要么依赖另一端关闭套接字并在catch块中执行清理时抛出的
IOException
,要么如果希望以干净的方式关闭,则发送一个特殊的“停止令牌”向另一个线程发送信号,告诉它您正在退出,并且它应该关闭其一端的套接字。

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

从javadoc:


因此,这里有两个选项:要么依赖另一端关闭套接字并在catch块中执行清理时抛出的
IOException
,要么如果希望以干净的方式关闭,则发送一个特殊的“停止令牌”发送到另一个线程,通知它您正在退出,并且它应该关闭其一端的套接字。

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

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

现在您的确切问题是什么?您必须从套接字读取数据,以正确检测它是否已启动已被另一方关闭。现在,您的确切问题是什么?您必须从套接字读取数据,以正确检测它是否已被另一方关闭。是的,我确定,我实际上成功地在客户端和服务器聊天界面之间聊天,并且工作正常。是的,我确定,事实上,我成功地在客户端和服务器聊天界面之间进行了聊天,效果非常好。是的,不同的人有不同的解决方案,如果问题是这样解决的,为什么你的教授会发疯呢?是的,这是肯定的。如果另一方“意外”关闭连接,则抛出异常只是正常行为。使用它没有什么错如果您可以调整您的协议,将“流结束”通知发送到另一端,当然,这也可能有效。-哦,还有:除了通过异常之外,String readline()还应该如何向调用方发出连接断开的信号呢?是的,不同的人有不同的解决方案,如果问题是这样解决的,为什么你的教授会发疯呢?是的,这是肯定的。如果另一方“意外”关闭连接,则抛出异常只是正常行为。使用它没有什么错如果您可以调整您的协议,将“流结束”通知发送到另一端,当然,这也可能有效。-哦,还有:除了通过异常之外,String readline()还应该如何向调用方发出连接已断开的信号?
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