簡體   English   中英

奇怪的Java套接字行為(連接但不發送)

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

我有一個相當復雜的項目,可以歸結為一個通過對象流進行通信的簡單客戶端/服務器。

對於兩個連續的連接(我連接一次,工作,斷開連接,然后再次連接,工作和斷開連接),一切工作正常。 客戶端進行連接,開展業務,然后關閉。 服務器成功關閉了對象輸出流和套接字,沒有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.");
    }
}

謝謝所有可能提供幫助的人!

(1)什么是ObjectInputBuffer和ObjectOutputBuffer? 您是說ObjectInputStream和ObjectOutputStream嗎?

(2)如果這樣,在創建ObjectOutputStream之后立即調用reset()只是浪費時間和帶寬。

(3)為什么在創建輸出流的異常上打印“無法獲得輸入”?

(4)當您遇到異常時,應該始終打印消息-不要用您自己的消息完全替代它,這只是丟掉了有用的信息。

(5)您假定讀取時出現任何 IOException表示流的結尾。 只有EOFException表示。 任何其他IOException都應打印或記錄。 顯然,您在這里遇到了其他一些異常而忽略了它。

(6)為什么繼續發送相同的對象?

從ObjectInputStream API讀取readUnshared():

從ObjectInputStream讀取“非共享”對象。 此方法與readObject相同,除了它防止隨后對readObject和readUnshared的調用返回對通過此調用獲得的反序列化實例的附加引用。

這可能是問題嗎? 使用readObject()代替。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM