7

好的,我有一个名为“客户端”的线程类,每次服务器接受连接时,它都会创建一个新客户端..运行方法侦听来自客户端的消息,我正在使用 ObjectInputStream ..

   do {            
         ObjectInputStream in = null;

        try {
            in = new ObjectInputStream(socket.getInputStream());
            String message = (String) in.readObject();
            System.out.println(message);
            }
            catch (ClassNotFoundException ex) {
                isConnected = false;
                System.out.println("Progoramming Error");
            }
            catch (IOException ex) {
                isConnected = false;
                System.out.println("Server ShutDown");
                System.exit(0);
            }
    } while(isConnected);

我遇到的问题是,为什么每次循环时我都必须创建一个新的 ObjectInputStream ......如果我在循环结束时关闭输入流并且它再次循环以获取另一条消息,我会收到一个错误......请有人帮忙

4

2 回答 2

8

只为客户端连接创建一次 ObjectInputStream(在循环外),然后将 readObject 方法放入循环中。

这是一个工作测试类:

public class TestPrg {

    public static void main(String... args) throws IOException {
        ServerListener server = new ServerListener();
        server.start();

        Socket socketToServer = new Socket("localhost", 15000);
        ObjectOutputStream outStream = new ObjectOutputStream(socketToServer.getOutputStream());

        for (int i=1; i<10; i++) {
            try {
                Thread.sleep((long) (Math.random()*3000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Sending object to server ...");
            outStream.writeObject("test message #"+i);
        }
        System.exit(0);

    }

    static class ServerListener extends Thread {

        private ServerSocket serverSocket;

        ServerListener() throws IOException {
            serverSocket = ServerSocketFactory.getDefault().createServerSocket(15000);
        }

        @Override
        public void run() {
            while (true) {
                try {
                    final Socket socketToClient = serverSocket.accept();
                    ClientHandler clientHandler = new ClientHandler(socketToClient);
                    clientHandler.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class ClientHandler extends Thread{
        private Socket socket;
        ObjectInputStream inputStream;

        ClientHandler(Socket socket) throws IOException {
            this.socket = socket;
            inputStream = new ObjectInputStream(socket.getInputStream());
        }

        @Override
        public void run() {
            while (true) {
                try {
                    Object o = inputStream.readObject();
                    System.out.println("Read object: "+o);
                } catch (IOException e) {
                    e.printStackTrace();

                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

在此示例中,字符串通过 ObjectStream 发送。如果您收到 ClassNotFoundException (http://download.oracle.com/javase/6/docs/api/java/io/ObjectInputStream.html#readObject()) 并且使用独立的客户端和服务器程序,那么您可能会检查是否客户端和服务器都有要在其类路径中发送的对象的类。

于 2011-08-11T07:28:10.703 回答
0

我个人在使用 Sockets 和 ObjectIOStream 时遇到的问题是它会记住您所有的对象地址,因此每次您在客户端发送和接收它们时,如果发送对象的地址未更改,它将从缓冲区复制。普通

  • 或者每次发送它们时创建新对象(这不是一个坏主意,因为 ObjectIOStream 似乎对此缓冲区有限制)
  • 或为这些 perpouse 使用另一个 Stream
于 2022-02-21T19:34:03.307 回答