2010-10-27 192 views
3

我有下面的代碼,從一個讀取與QTcpSocket:如何正確確定在QTCPSocket中已達到輸入結束?

QString request; 

while(pSocket->waitForReadyRead()) 
{ 
    request.append(pSocket->readAll()); 
} 

這段代碼的問題是,它讀取所有的輸入,然後在最後30秒暫停。 (這是默認超時。)

什麼是避免長時間超時並檢測到輸入已達到結束的正確方法? (避免信號的答案是首選,因爲這應該是在一個線程中同步發生的。)

回答

2

要確定的唯一方法是當您收到您期望的確切字節數。這通常是通過在數據包開始時發送數據的大小來完成的。先閱讀,然後繼續循環,直到完全掌握。另一種方法是使用標記,即標記數據結尾的特定字節序列,但這通常會變得混亂。

+0

嗯,這是一個HTTP請求處理程序,所以發送「Content-length」頭的任何HTTP請求都將很容易處理。 – 2010-10-27 05:08:43

+1

您還需要添加一些超時,因爲如果有人會攻擊您的服務,它可能會發送內容長度,並且不發送任何數據。我覺得30秒超時很多。也許你應該像嘗試5次超時重試3次,並假設連接中斷 – 2010-10-27 07:56:28

+1

+1這是正確的答案。這是TCP,一個流媒體協議。您必須解釋流,以確定輸入是否已完全傳輸。 – andref 2010-10-28 20:06:55

0

如果您正在處理的情況類似於不包含內容長度的HTTP響應,並且您知道一旦發送數據,另一端將關閉連接,那麼還有其他解決方案。

  1. 使用socket.setReadBufferSize確保有足夠的讀取緩衝區來存放所有可能發送的數據。
  2. 呼叫socket.waitForDisconnected等待遠端關閉連接
  3. 使用socket.bytesAvailable爲內容長度

這工作,因爲連接的關閉不放棄任何緩衝數據一個QTcpSocket。

+0

有點額外的信息:將Connection:close頭添加到HTTP請求中,要求服務器在完成發送數據後顯式關閉連接。 – 2011-09-22 07:12:20