奇怪的 Java 套接字行为(连接,但不发送)

发布于 2024-09-02 10:26:12 字数 2317 浏览 13 评论 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.");
    }
}

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

I have a fairly complex project that boils down to a simple Client / Server communicating through object streams.

Everything works flawlessly for two consecutive connections (I connect once, work, disconnect, then connect again, work, and disconnect). The client connects, does its business, and then closes. The server successfully closes both the object output stream and the socket, with no IO errors.

When I try to connect a third time, the connection appears to go through (the ServerSocket.accept() method goes through and an ObjectOutputStream is successfully created). No data is passed, however. The inputStream.readUnshared() method simply blocks.

I have taken the following memory precautions:

  1. When it comes time to close the sockets, all running threads are stopped, and all objects are nulled out.
  2. After every writeUnshared() method
    call, the ObjectOutputBuffer is
    flushed and reset.

Has anyone encountered a similar problem, or does anyone have any suggestions? I'm afraid my project is rather large, and so copying code is problematic.

The project boils down to this:

SERVER MAIN

ServerSocket serverSocket = new ServerSocket(port);

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

WORK THREAD (SERVER)

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.");
    }
}

CLIENT

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.");
    }
}

Thank you to everyone who may be able to help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

童话 2024-09-09 10:26:12

(1)什么是ObjectInputBuffer和ObjectOutputBuffer?您的意思是 ObjectInputStream &对象输出流?

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

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

(4) 当您遇到异常时,您应该始终打印它的消息 - 不要完全用您自己的消息替换它,那只是丢弃有用的信息。

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

(6) 为什么你总是发送同一个对象?

(1) What's ObjectInputBuffer and ObjectOutputBuffer? Did you mean ObjectInputStream & ObjectOutputStream?

(2) If so, calling reset() immediately after creating the ObjectOutputStream is just a waste of time and bandwidth.

(3) Why are you printing 'could not get an input' on an exception creating an output stream?

(4) When you get an exception you should always print its message - don't completely substitute it with your own, that's just throwing away useful information.

(5) You are assuming that any IOException when reading means the end of the stream. Only EOFException means that. Any other IOException should be printed or logged. Clearly you are getting some other exception here and ignoring it.

(6) Why do you keep sending the same object?

荒路情人 2024-09-09 10:26:12

来自 readUnshared() 的 ObjectInputStream API:

从中读取“非共享”对象
对象输入流。这个方法是
与 readObject 相同,除了
它会阻止后续调用
readObject 和 readUnshared from
返回对的附加引用
通过获得的反序列化实例
这次通话。

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

From ObjectInputStream API for readUnshared():

Reads an "unshared" object from the
ObjectInputStream. This method is
identical to readObject, except that
it prevents subsequent calls to
readObject and readUnshared from
returning additional references to the
deserialized instance obtained via
this call.

Could this be the problem? Use readObject() instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文