Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么client input.readObject有时返回;空";有时效果很好?_Java_Sockets - Fatal编程技术网

Java 为什么client input.readObject有时返回;空";有时效果很好?

Java 为什么client input.readObject有时返回;空";有时效果很好?,java,sockets,Java,Sockets,我正在尝试制作一个使用tcp java连接的客户机/服务器程序,并使用localhost IP和端口12345在同一台机器(服务器和客户机)上测试它 我使用ObjectInputStream和ObjectOutputStream来接收和发送消息。 有时我的程序运行得很好,它可以根据我的需要发送正确的消息,但是有时(在程序的随机时间/阶段)我的一个客户“失去”连接,他进入无限循环打印“null”或“无效类型代码:54”不进行任何代码更改 我没有收到任何错误,只是服务器在循环中打印“连接重置”,客户

我正在尝试制作一个使用tcp java连接的客户机/服务器程序,并使用localhost IP和端口12345在同一台机器(服务器和客户机)上测试它

我使用ObjectInputStream和ObjectOutputStream来接收和发送消息。 有时我的程序运行得很好,它可以根据我的需要发送正确的消息,但是有时(在程序的随机时间/阶段)我的一个客户“失去”连接,他进入无限循环打印“null”“无效类型代码:54”不进行任何代码更改

我没有收到任何错误,只是服务器在循环中打印“连接重置”,客户端从捕获(IOException e)中打印“空”或“无效类型代码:54”

我将向您展示我的代码的基本内容

服务器:

    public static void main(String[] args) {
    //--------BASIC CODE used for connection stuff below----//
         server = new ServerSocket(12345);
         connection =server.accept();
         Thread thread =new Thread(new ClientThread(connection,GRM...));
         thread.start();
         output = new ObjectOutputStream(connection.getOutputStream());
         output.flush();
         input = new ObjectInputStream(connection.getInputStream());
    }
    --------------//---------thread for each client----------//--------------
    do{
           try{
             message=(String) input.readObject();
             if(message.startsWith("SOMENTHING"))//...some tcode
             if(message.equals("SEND")){
                 String message="hi";
                 output.writeObject("Chat:"+message);output.flush();
                 UserW.writeObject(message);UserW.flush();
                 //UserW is an output from another client stored in the server
             }
             catch(ClassNotFoundException classNotFoundException){
                System.out.print("\nUnknown object");
             }catch (IOException e) {
                System.out.println(e.getMessage());
             }    
     }while(!message.equals("DISCONNECT"));
客户:

        public static void main(String[] args) {
        connection=new Socket(InetAddress.getByName("127.0.0.1"),12345);
        //...... same logic with streams......//
        }
        //-------thread that receives from server-----//
        do{
          try{
           String message=(String) input.readObject();
           //.....some code....//
          }catch( ClassNotFoundException classNotFoundException){
            System.out.print("\nUnknown object");
          }catch (IOException e) {
            System.out.println(e.getMessage());
          }
        }while(true);

因此,我用我创建的另一个更简单的服务器/客户机程序进行了一些测试 我认为,当服务器同时发送两条或多条消息时,客户端的input.read()会变得“混乱”,无法正确读取消息,从而使服务器进行“连接重置”,客户端会给出“无效代码”错误

我对这个问题的解决方案(有效)是在服务器站点上创建一个向客户端发送消息的同步方法,但我不喜欢它,因为服务器性能会降低(我认为)。作为第二个解决方案,我在客户端站点上考虑制作一些类似缓冲区的东西,但我不知道这是否可行

如果有人有更好的解决办法,我很乐意听

更新:最佳解决方案是使用BufferedReader进行输入,使用PrintWriter进行输出,而不是使用流

另外,非常感谢阿塞托夫,他指引我走上了正确的道路

为什么客户端
readObject()
有时返回null

事实并非如此
readObject()
未返回null。您在
catch
块中打印null,因为您捕获了一个没有消息的
IOException
,例如可能是
eofeexception
,这将导致您关闭套接字并中断读取循环

实际问题是一个并发问题,如下所示:

Thread thread =new Thread(new ClientThread(connection,GRM...));
thread.start();
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());

输出
输入
变量应该是
ClientThread
的成员,而不是此类,它们应该在
ClientThread.run()
中初始化,而不是在其构造函数中初始化,当然也不是在这里初始化

您似乎在同一服务器套接字上打开了两个ObjectOutputStream,这可能是导致此错误的原因。我为每个新连接打开了一个ObjectOutputStream,并在一个新线程中处理它们…如果您的意思是否,我的意思是您的服务器有
output.writeObject;UserW.writeObject这似乎表明一个线程(您的服务器)处理两个ObjectOutputStream,这在allOk不是一个好主意我明白您的意思,但我看过一个聊天应用程序的教程,它也做了同样的事情来向其他人广播消息。UserW是存储在服务器中的另一个客户端套接字输出的引用…另一方面,当我必须向其他人发送消息时,我的问题最为明显,因此你可能有一个观点。但是我应该如何向其他人发送消息呢?无需相信我,检查或此处:最坏的情况是,您可以在两个调用之间尝试
ObjectOutputStream.reset()
。由于变量作用域错误,您只有多个线程使用相同的流。此解决方案将所有I/O顺序化到所有客户端。一点也不可取。我解决了我的问题,我已经写了答案。我不明白你的意思可能我的java知识不太好