当前位置: 首页 > 知识库问答 >
问题:

服务器客户端程序中Java IOException流关闭

高砚
2023-03-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);
    }
}

下面是异常的stacktrace:

java.io.ioException:在java.base/java.io.BufferedInputStream.getBufifOpen(BufferedInputStream.java:176)在java.base/java.io.BufferedInputStream.java:342)在java.base/sun.nio.cs.streamDecoder.readBytes(streamDecoder.java:284)在java.base/sun.nio.cs.streamDecoder.impread(streamDecoder.java:326)在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)

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

共有1个答案

匡翰
2023-03-14

由于试图从已不存在的bufferedreader中读取,特别是1中的,因此出现异常。在第一次运行时,所有流和读取器都按它们应该的方式打开,但是在从客户端获得命令close后,服务器将在1中关闭。然后,当客户机尝试重新连接时,程序尝试将1.readline()中的值赋给ServerMsg,该值是字符串,但是由于中的不再是,因此出现IOException,因为BufferedReader是关闭的,不能从中读取任何内容。

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

希望这能有所帮助。

 类似资料:
  • 问题内容: 我正在尝试使用我一直在努力的客户端/服务器程序实现多线程。我需要允许多个客户端同时连接到服务器。我目前有4类:客户端,服务器,协议和用于处理线程的工作器。以下代码是我对这些类的拥有的代码: SocketServer类: SocketClient类别: 协议类别: ClientWorker类: 当我运行服务器和客户端时,一切正常。然后,当我尝试运行另一个客户端时,它只是挂在那儿,没有提示

  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se

  • 我想同步2个集合。如果服务器端有什么变化,连接的客户端就会更新。我有一个非常基本的问题。我现在需要复制我的java项目,并在一个项目中编程服务器,在另一个项目中编程客户端吗?但这听起来像是相当多不必要的工作。我不能在一个项目中实现这一切,然后在一个主项目中启动服务器和客户端吗?我需要线程吗?我有点纠结于最好的方法是什么。提前谢谢。

  • 前面的章节介绍了所有 Redis 的重要功能组件: 数据结构、数据类型、事务、Lua 环境、事件处理、数据库、持久化, 等等, 但是我们还没有对 Redis 服务器本身做任何介绍。 不过, 服务器本身并没有多少需要介绍的新东西, 因为服务器除了维持服务器状态之外, 最重要的就是将前面介绍过的各个功能模块组合起来, 而这些功能模块在前面的章节里已经介绍过了, 所以本章将焦点放在服务器的初始化过程,

  • 问题内容: 我正在尝试以客户端/服务器方式制作Java应用程序。客户端是SWT中的GUI,它显示来自服务器的数据。服务器已连接到数据库。 好的,对此感到抱歉,我确定这是一个经典问题,但我不知道如何开始。 在我为他们工作的一个项目中,他们实施了很多魔术来透明地调用Glassfish服务器。 我不想使用Glassfish服务器。我只想要简单的Java语言。但是代理的概念似乎很酷。 你有这种想法或例子吗

  • 我想用java写一个传输文件套接字程序。但我有问题,如何取消时传输文件。 当我在客户端关闭inputstream时,服务器如何知道它关闭了outputstream。 这是我的代码:客户 ...... 服务器 ...... 但当我关闭inputstream时没有显示任何内容