2011-11-20 33 views
2

服務器是否可能知道客戶端已經完成數據發送並且現在已準備好進行響應 - 無論(並且沒有知識)應用協議?服務器是否可能知道TCP流已經「完成」而不管協議?

編輯: 想想創建一個代理服務器。你不能影響協議,你不知道每個協議的應用細節(所以你不知道流何時「結束」)。關於「客戶可能關閉輸入流」 - 這是真的,但顯然客戶並沒有真正關閉流(與重用有關)。這是通過Web瀏覽器進行實證測試的。

雖然我可能會在錯誤的樹上吠叫 - 對於那個代理服務器場景,不會將流複製到「另一端」的輸出流就夠了嗎?但是,另一端如何「知道」該流已結束?

看到這個程序:

public class Test { 
public static void main(String[] args) throws IOException { 
    ServerSocket serverSocket = new ServerSocket(8081, 100, InetAddress.getByName("localhost")); 
    final Socket socket1 = new Socket("www.google.com", 80); 
    final Socket socket = serverSocket.accept(); 
    new Thread(new Runnable() { 
     public void run() { 
      try { 
       final InputStream inputStream = socket1.getInputStream(); 
       final OutputStream outputStream = socket.getOutputStream(); 
       readwrite(inputStream, outputStream, false); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
    final InputStream inputStream = socket.getInputStream(); 
    final OutputStream outputStream1 = socket1.getOutputStream(); 
    readwrite(inputStream, outputStream1, true); 

} 

private static void readwrite(InputStream inputStream, OutputStream outputStream1, boolean x) throws IOException { 
    final byte[] bytes = new byte[4]; 
    int read = -1; 
    while ((read = inputStream.read(bytes)) != -1) { 
     System.out.println((x?"s ":"r ") + new String(bytes)); 
     outputStream1.write(bytes, 0, read); 
    } 
} 
} 

而不是做什麼,你會覺得它會做(在瀏覽www.google.com代理)的它只是掛起。應該從google讀取並寫入本地套接字的線程不會檢測到該輸入流中的任何內容。

編輯2: DOH! 把我放在愚蠢的角落。忘了「開始」線程。 回到我原來的問題 - 我怎麼知道流已經結束?

編輯3: 那麼,我的問題是完全不同的(與POST,Transfer-Encoding和HttpClient惱人的內部緩存 - 不能關閉)。 爲了公平起見,我會接受最好回答原始問題的答案。

回答

1

如果'已完成'表示TCP的入站或出站流已關閉(所謂的半關閉連接),則可以。如果inputStream.read(bytes)返回-1,則入境流將關閉。

如果'完成'意味着別的東西,那麼答案是否定的。

如果您打算實施通用代理,那麼您應該同時等待來自兩個套接字的數據。並將任何傳入數據寫入其他套接字。 如果另一個套接字不可寫,您也應該停止讀取套接字。否則你必須緩衝數據。代理服務器也應該處理半關閉連接。

當傳送的協議具有消息邊界時,不要嘗試檢測,因爲某些協議可能會一直向兩個方向傳輸數據。

0

不 - 但您可以使用非阻塞式讀取超時,它會告訴您沒有更多數據進入。這可以解決問題。

0

客戶端的TCP會話將同時具有入站和出站流。客戶端可能在發送請求後關閉其出站流,並將其入站流打開以接收響應。服務器會檢測到這種情況,同時仍能夠回覆。

相關問題