首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java如何用ObjectInputStream阅读

Java如何用ObjectInputStream阅读
EN

Stack Overflow用户
提问于 2019-06-07 19:07:20
回答 1查看 189关注 0票数 1

这是我第一次使用套接字,为了更好地了解发生了什么,我决定构建一个可以支持多个用户的客户端服务器聊天应用程序。

起初,我使用DataInputStream / DataOutputStream进行通信,一切工作正常。但我想换成ObjectStream,这就是问题所在。一旦我用ObjectInputStream / ObjectOutputStream替换了所有的DataInputStream / DataOutputStream,我就不能再打印检索到的数据。

这是我之前使用的代码,它是有效的(DataStream):

服务器:

代码语言:javascript
运行
复制
       try {
            DataInputStream in = new DataInputStream(socket.getInputStream());
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());

            out.writeUTF("HI FROM SERVER");
            while (!socket.isClosed()) {
                try {
                    if (in.available() > 0) {
                        String input = in.readUTF();
                        for (ClientThread thatClient : server.getClients()){
                            DataOutputStream outputParticularClient = new DataOutputStream(thatClient.getSocket().getOutputStream());
                            outputParticularClient.writeUTF(input + " GOT FROM SERVER");
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

客户端:

代码语言:javascript
运行
复制
try {
    socket = new Socket("localhost", portNumber);


    DataInputStream in = new DataInputStream(socket.getInputStream());
    new Thread(()->{
        while(!socket.isClosed()){
            try {
                if (in.available() > 0){
                    String input = in.readUTF();
                    System.out.println(getUserName() + " > " + input);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
} catch (IOException e) {
    e.printStackTrace();
}

这就是我尝试用ObjectStream实现同样的想法的方法:

服务器:

代码语言:javascript
运行
复制
try {
    ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
    ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());

    while (!socket.isClosed()) {
        try {
            if (in.available() > 0) {
                Message input;
                try {
                    input = (Message)in.readObject();
                    if (input.equals(null)){
                        System.err.println("SERVER RETRIEVED NULL OBJECT");
                    }
                    for (ClientThread thatClient : server.getClients()){
                        ObjectOutputStream outputParticularClient = new ObjectOutputStream(thatClient.getSocket().getOutputStream());
                        outputParticularClient.writeObject(input);
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
} catch (IOException e) {
    e.printStackTrace();
}

客户端:

代码语言:javascript
运行
复制
try {
            socket = new Socket(getHost(), portNumber);

            ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
            new Thread(()->{
                while(!socket.isClosed()){
                    try {
                        if (in.available() > 0){
                            Message input = null;
                            try {
                                input = (Message)in.readObject();
                                if (input.equals(null)){
                                    System.err.println("CLIENT RETRIEVED NULL OBJECT");
                                }
                                System.out.println("CLIENT " + input.toString());
                            } catch (ClassNotFoundException e) {
                                e.printStackTrace();
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        } catch (IOException e) {
            e.printStackTrace();
        }

我觉得这与if语句if (in.available() > 0)有关,但我不能确切地说出发生了什么。

EN

回答 1

Stack Overflow用户

发布于 2019-06-08 00:25:32

available()的作用可能与您想象的不同,而且它在生产代码中几乎没有用处(对于ObjectInputStream来说尤其如此)。您没有收到任何数据的原因实际上是,正如您已经怀疑的那样,in.available()总是返回0

正如注释中所指出的,StreamCorruptedException是由于写入已使用ObjectOutputStream的另一个实例写入的现有ObjectInputStream而导致的。请参阅答案StreamCorruptedException: invalid type code: AC以获得更多解释。

下面是一些快捷的示例代码,其中包含一个服务器回显来自两个客户端的消息。它不是干净的,但它可能会让你知道如何处理你的问题:

代码语言:javascript
运行
复制
public class SO56493162 {

   private static final class Message implements Serializable {
      private static final long serialVersionUID = 1L;
      private static int cnt = 0;
      private final int id;

      public Message(int id) {
         ++cnt;
         this.id = id;
      }

      public String toString() {
         return "Msg from " + id + " : " + cnt;
      }
   }

   private static final class Client implements Runnable {
      private InetSocketAddress addr = null;
      private int id = -1;

      Client(InetSocketAddress addr, int id) {
         this.addr = addr;
         this.id = id;
      }

      public void run() {
         int timeout = 3000;
         Socket s = null;
         try {
            s = new Socket();
            s.connect(addr, timeout);
            ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
            ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
            System.out.println("Client " + id + " connected");
            while (true) {
               Thread.sleep(new Random().nextInt(2000));
               Message hello = new Message(id);
               oos.writeObject(hello);
               oos.flush();
               Message reply = (Message) ois.readObject();
               System.out.println("Reply: " + reply.toString());
            }
         } catch (Exception e) {
            e.printStackTrace();
         } finally {
            try {
               s.close();
            } catch (Exception ignore) {
            }
         }
      }
   }

   private static final class Server implements Runnable {
      private ServerSocket sock = null;

      Server(ServerSocket sock) throws IOException {
         this.sock = sock;
      }

      public void run() {
         System.out.println("starting server");
         try {
            while (true) {
               final Socket client = sock.accept();
               System.out.println("connection accepted");
               Thread t = new Thread(new Runnable() {
                  @Override
                  public void run() {
                     try {
                        ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
                        ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
                        while (!client.isClosed()) {
                           try {
                              Message input = (Message) ois.readObject();
                              oos.writeObject(input);
                              oos.flush();
                           } catch (EOFException eof) {
                              System.err.println("EOF!");
                              client.close();
                           }
                        }
                     } catch (Exception e) {
                        e.printStackTrace();
                     }
                  }
               });
               t.setDaemon(true);
               t.start();
            }
         } catch (Exception e) {
            e.printStackTrace();
         }
      }
   }

   public static void main(String args[]) throws IOException, InterruptedException {
      final int port = 9876;

      Thread ts = new Thread(new Runnable() {
         @Override
         public void run() {
            try {
               new Server(new ServerSocket(port)).run();
            } catch (Exception e) {
               e.printStackTrace();
            }
         }
      });
      ts.setDaemon(true);
      ts.start();

      InetSocketAddress addr = new InetSocketAddress("localhost", port);

      for (int i = 0; i < 2; ++i) {
         Client cl = new Client(addr, i);
         Thread tc = new Thread(cl);
         tc.setDaemon(true);
         tc.start();
      }

      Thread.sleep(10000);
      System.err.println("done");
   }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56493162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档