简体   繁体   English

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

[英]Strange Java Socket Behavior (Connects, but Doesn't Send)

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. 服务器成功关闭了对象输出流和套接字,没有IO错误。

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). 当我尝试第三次连接时,连接似乎通过了(ServerSocket.accept()方法通过并成功创建了ObjectOutputStream)。 No data is passed, however. 但是,没有数据传递。 The inputStream.readUnshared() method simply blocks. inputStream.readUnshared()方法只是阻塞。

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. 每次调用writeUnshared()方法之后,都会刷新并重置ObjectOutputBuffer。

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! 谢谢所有可能提供帮助的人!

(1) What's ObjectInputBuffer and ObjectOutputBuffer? (1)什么是ObjectInputBuffer和ObjectOutputBuffer? Did you mean ObjectInputStream & ObjectOutputStream? 您是说ObjectInputStream和ObjectOutputStream吗?

(2) If so, calling reset() immediately after creating the ObjectOutputStream is just a waste of time and bandwidth. (2)如果这样,在创建ObjectOutputStream之后立即调用reset()只是浪费时间和带宽。

(3) Why are you printing 'could not get an input' on an exception creating an output stream? (3)为什么在创建输出流的异常上打印“无法获得输入”?

(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. (4)当您遇到异常时,应该始终打印消息-不要用您自己的消息完全替代它,这只是丢掉了有用的信息。

(5) You are assuming that any IOException when reading means the end of the stream. (5)您假定读取时出现任何 IOException表示流的结尾。 Only EOFException means that. 只有EOFException表示。 Any other IOException should be printed or logged. 任何其他IOException都应打印或记录。 Clearly you are getting some other exception here and ignoring it. 显然,您在这里遇到了其他一些异常而忽略了它。

(6) Why do you keep sending the same object? (6)为什么继续发送相同的对象?

From ObjectInputStream API for readUnshared(): 从ObjectInputStream API读取readUnshared():

Reads an "unshared" object from the ObjectInputStream. 从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. 此方法与readObject相同,除了它防止随后对readObject和readUnshared的调用返回对通过此调用获得的反序列化实例的附加引用。

Could this be the problem? 这可能是问题吗? Use readObject() instead. 使用readObject()代替。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM