0

我有一个相当复杂的项目,归结为通过对象流进行通信的简单客户端/服务器。

对于两个连续的连接(我连接一次,工作,断开连接,然后再次连接,工作和断开连接),一切都完美无缺。客户端连接,执行其业务,然后关闭。服务器成功关闭对象输出流和套接字,没有 IO 错误。

当我尝试第三次连接时,连接似乎已通过(ServerSocket.accept() 方法通过并成功创建了 ObjectOutputStream)。然而,没有数据被传递。inputStream.readUnshared() 方法只是阻塞。

我采取了以下内存预防措施:

  1. 当需要关闭套接字时,所有正在运行的线程都会停止,并且所有对象都被清空。
  2. 每次调用 writeUnshared() 方法后,都会刷新并重置 ObjectOutputBuffer。

有没有人遇到过类似的问题,或者有没有人有什么建议?恐怕我的项目比较大,所以复制代码是有问题的。

该项目归结为:

服务器主

ServerSocket serverSocket = new ServerSocket(port);

while (true) {
    new WorkThread(serverSocket.accept()).start();
}

工作线程(服务器)

public void run() {
    ObjectInputBuffer inputBuffer = new ObjectInputBuffer(new BufferedInputStream(socket.getInputStream()));

    while (running) {
         try {
              Object myObject = inputBuffer.readUnshared();

              // do work is not specified in this sample
              doWork(myObject);
         } catch (IOException e) {   
              running = false;
         }
    }

    try {
         inputBuffer.close();
         socket.close(); 
    } catch (Exception e) {
         System.out.println("Could not close.");
    }
}

客户

public Client() {
    Object myObject;
    Socket mySocket = new Socket(address, port);

    try {
         ObjectOutputBuffer output = new ObjectOutputBuffer(new BufferedOutputStream(mySocket.getOutputStream()));

         output.reset();
         output.flush();
    } catch (Exception e) {
         System.out.println("Could not get an input.");
         mySocket.close();
         return;
    }

    // get object data is not specified in this sample. it simply returns a serializable object
    myObject = getObjectData();

    while (myObject != null) {
         try {
              output.writeUnshared(myObject);
              output.reset();
              output.flush();
         } catch (Exception e) {
              e.printStackTrace();
              break;
         } // catch
    } // while

    try {
         output.close();
         socket.close();
    } catch (Exception e) { 
         System.out.println("Could not close.");
    }
}

感谢所有可能提供帮助的人!

4

2 回答 2

2

(1)什么是ObjectInputBuffer和ObjectOutputBuffer?您是说 ObjectInputStream 和 ObjectOutputStream 吗?

(2) 如果是这样,在创建 ObjectOutputStream 之后立即调用 reset() 只是浪费时间和带宽。

(3) 为什么在创建输出流的异常上打印“无法获得输入”?

(4) 当你得到一个异常时,你应该总是打印它的消息——不要完全用你自己的代替它,那只是丢掉有用的信息。

(5) 您假设读取时的任何IOException 都意味着流的结束。只有 EOFException 意味着。应打印或记录任何其他 IOException。显然,您在这里遇到了其他一些异常并忽略了它。

(6) 为什么你一直发送相同的对象?

于 2010-05-22T01:15:31.380 回答
0

来自 readUnshared() 的 ObjectInputStream API:

从 ObjectInputStream 中读取一个“非共享”对象。此方法与 readObject 相同,只是它阻止对 readObject 和 readUnshared 的后续调用返回对通过此调用获得的反序列化实例的附加引用。

这可能是问题吗?请改用 readObject()。

于 2010-05-22T02:08:00.207 回答