【问题标题】:Java IOException Stream Closed in Server Client programJava IOException 流在服务器客户端程序中关闭
【发布时间】:2019-12-24 01:53:14
【问题描述】:

我正在尝试制作一个服务器客户端程序,该程序允许从服务器向客户端发送多条消息,反之亦然,而无需等待响应。当第一个客户端连接和断开连接时,该程序工作正常。但是当我再次连接客户端时,我得到了错误。这是我的服务器代码:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

import java.io.InputStreamReader;

import java.io.BufferedReader;

class Q2Server implements Runnable{
    private ServerSocket serverSocket;
    private Socket socket;
    private DataOutputStream out;
    private BufferedReader in1;
    private DataInputStream in2;
    private Thread read, write;
    private String clientMsg, serverMsg;

    public Q2Server (int port) throws IOException{
        serverSocket = new ServerSocket(port);

        while(true) {
            try {
                System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
                socket = serverSocket.accept();

                System.out.println("Just connected to " + socket.getRemoteSocketAddress());

                out = new DataOutputStream(socket.getOutputStream());
                out.writeUTF("Thanks for connecting to " + socket.getLocalSocketAddress());

                clientMsg = "";
                serverMsg = "";

                read = new Thread(this);
                write = new Thread(this);

                read.start();
                write.start();

                read.join();
                write.join();

            } catch(IOException e) {
                e.printStackTrace();
            } catch(InterruptedException ie) {
                ie.printStackTrace();
            }
        }

    }

    public void run () {
        try {
            if(Thread.currentThread() == write) {
                while(true) {
                    try {
                        if(clientMsg.equals("close")) {
                            break;
                        } else {
                            in1 = new BufferedReader(new InputStreamReader(System.in));
                            out = new DataOutputStream(socket.getOutputStream());
                            serverMsg = in1.readLine();
                            out.writeUTF(serverMsg);
                            if(serverMsg.equals("close")) {
                                socket.close();
                                in1.close();
                                in2.close();
                                out.close();
                                System.out.println("Closing connection...");
                                break;
                            }    
                        }
                    } catch (SocketException s) {
                        break;
                    } 

                } 

            } else {
                while(true) {
                    try {
                        if(serverMsg.equals("close")) {
                            break;
                        }
                        in2 = new DataInputStream(socket.getInputStream());
                        clientMsg = in2.readUTF();
                        System.out.println("Client: " + clientMsg);
                        if(clientMsg.equals("close")) {
                            socket.close();
                            in1.close();
                            in2.close();
                            out.close();
                            System.out.println("Closing connection...");
                            break;
                        }
                    } catch(SocketException s) {
                        break;
                    } 

                } 

            }
        } catch (IOException i) {
            i.printStackTrace();
        }
    }
    public static void main(String[] args) throws IOException {
        Q2Server server = new Q2Server(8080);
    }
}

客户端代码:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.rmi.UnexpectedException;


import java.io.InputStreamReader;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.lang.Thread;

class Q2Client implements Runnable {
    private Socket socket;
    private Thread read, write;
    private BufferedReader in1;
    private DataInputStream in2;
    private DataOutputStream out;
    private String clientMsg, serverMsg;

    public Q2Client(int port) {
        try {
            socket = new Socket("localHost",port);
            System.out.println("Connected to port: " + port);

            clientMsg = serverMsg = "";

            read = new Thread(this);
            write = new Thread(this);

            in2 = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

            System.out.println(in2.readUTF());

            read.start();
            write.start();

            read.join();
            write.join();

        } catch(UnexpectedException u) {
            u.printStackTrace();
        } catch(IOException i) {
            i.printStackTrace();
        } catch(InterruptedException ie) {
            ie.printStackTrace();
        }
    }

    public void run() {
        try {
            if(Thread.currentThread() == write) {
                while(true) {
                    try {
                        if(serverMsg.equals("close")) {
                            break;
                        }
                        in1 = new BufferedReader(new InputStreamReader(System.in));
                        out = new DataOutputStream(socket.getOutputStream());
                        clientMsg = in1.readLine();
                        out.writeUTF(clientMsg);
                        if(clientMsg.equals("close")) {
                            socket.close();
                            in1.close();
                            in2.close();
                            out.close();
                            System.out.println("Closing connection...");
                            break;
                        }
                    } catch (SocketException s) {
                        break;
                    } 

                } 
            } else {
                while(true) {
                    try {
                        if(clientMsg.equals("close")) {
                            break;
                        }
                        in2 = new DataInputStream(socket.getInputStream());
                        serverMsg = in2.readUTF();
                        System.out.println("Server: " + serverMsg);
                        if(serverMsg.equals("close")) {
                            socket.close();
                            in1.close();
                            in2.close();
                            out.close();
                            System.out.println("Closing connection...");
                            break;
                        }
                    } catch (SocketException s) {
                        break;
                    }

                } 
            }
        } catch (IOException i) {
            i.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Q2Client client = new Q2Client(8080);
    }
}

这是异常的堆栈跟踪:

java.io.IOException: 流关闭 在 java.base/java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:176) 在 java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:342) 在 java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) 在 java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) 在 java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) 在 java.base/java.io.InputStreamReader.read(InputStreamReader.java:185) 在 java.base/java.io.BufferedReader.fill(BufferedReader.java:161) 在 java.base/java.io.BufferedReader.readLine(BufferedReader.java:326) 在 java.base/java.io.BufferedReader.readLine(BufferedReader.java:392) 在 Q2Server.run(Q2Server.java:65) 在 java.base/java.lang.Thread.run(Thread.java:835)

当服务器或客户端发送“关闭”时,连接关闭。客户端可以再次连接。但是当我再次运行客户端代码时,我得到了异常。出了什么问题,我该如何解决?

【问题讨论】:

  • 您已共享状态但没有同步。这段代码的编写方式非常混乱。

标签: java multithreading sockets networking inputstream


【解决方案1】:

您遇到了一个异常,因为您尝试从不再存在的BufferedReader 中读取数据,尤其是in1。在第一次运行时,您的所有流和阅读器都按应有的方式打开,但在从客户端获取命令close 后,您的服务器将关闭in1。然后,当客户端尝试重新连接时,程序尝试将in1.readLine() 的值分配给serverMsg,即String,但由于in1 已不存在,因此IOException 出现自BufferedReader已关闭,无法从中读取任何内容。

我想既然您想让服务器保持运行,而客户端可以在任何给定时间连接和断开连接,这完全有道理,也许您不应该关闭为服务器提供键盘命令的BufferedReader在你的情况下。关闭它对我来说没有意义,因为当客户端断开连接时您并没有停止整个服务器,您只需关闭连接,但服务器仍然应该能够接受命令。

希望这会有所帮助。

【讨论】:

  • 我这样做了,现在我没有收到错误。但是在服务器向客户端发送“关闭”后,服务器断开连接,但客户端在关闭之前再接受一次输入。当客户端发送“关闭”时也会发生同样的情况,服务器会在关闭之前再输入一个。
  • @ShantanuShinde 是的,我也注意到了。这只是您编写代码的方式。调试器可以帮助您自己查看这一点,并可能修复此行为。
  • 我试过了,即使在第一个线程关闭后,另一个线程也会继续执行。我该如何解决?我放了一个 if 语句,但它似乎在 if 内部切换。
  • @ShantanuShinde 这种结构的意义何在? if(serverMsg.equals("close")) { break; 当客户端从服务器收到关闭命令时,您的 porgram 不会做任何事情,反之亦然。
  • 它关闭套接字。此外,serverMsgclientMsg 的值变为“关闭”。所以另一个线程将进入ifbreak
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
相关资源
最近更新 更多