【问题标题】:Java - Listening to a socket with ObjectInputStreamJava - 使用 ObjectInputStream 监听套接字
【发布时间】:2011-08-11 07:04:44
【问题描述】:

好的,我有一个名为“Client”的线程类,每次服务器接受连接时,它都会创建一个新的 Client..run 方法侦听来自客户端的消息,我正在使用 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...如果我在循环结束时关闭输入流并再次循环以获取另一条消息,我将收到错误...请有人帮忙

【问题讨论】:

  • 您不必,也不应该这样做。
  • 获得 ClassNotFoundException 既不是您不再连接的指示,也不是编程错误。它表示部署错误。
  • 您能否解决您遇到的错误,如果您也发布客户端代码也会有所帮助。
  • isConnected() 不是活动连接的有效测试。连接一直到您读取流结束,或出现 SocketTimeoutException 以外的 IOException

标签: java sockets objectinputstream


【解决方案1】:

只为客户端连接创建一次 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()) 并且使用独立的客户端和服务器程序,那么您可能会检查是否客户端和服务器都有要在其类路径中发送的对象的类。

【讨论】:

  • 哦,我明白了......谢谢那个哥们......我稍后会试试......然后告诉你它是怎么回事......
  • 睡眠是没有意义的,读取循环应该捕获EOFException并在捕获时跳出读取循环。除了SocketTimeoutException 之外的所有其他IOExceptions 对连接也是致命的,应该退出读取循环。出于任何原因退出读取循环后,应关闭套接字。这里有太多不好的做法。
  • 不会多次读取同一个对象吗?在客户端处理程序中?或者 ObjectInputStream 中是否有某种自动功能可以防止它发生?为什么那个循环不会多次读取同一个对象?
【解决方案2】:

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

  • 或在每次发送时创建新对象(这不是一个坏主意,因为 ObjectIOStream 似乎对此缓冲区有限制)
  • 或为这些目的使用另一个流

【讨论】:

    猜你喜欢
    • 2011-02-15
    • 2013-03-29
    • 2017-09-06
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 2014-04-17
    相关资源
    最近更新 更多