2012-11-08 34 views
0

我在QT中進行套接字編程,我必須設計一個通過TCP/IP傳輸數據的協議。通過套接字修改數據包大小

現在我的協議設計很簡單。它以一種方式發送命令,每寫入一次,寫入套接字的數據的第一個字節就是命令。因此,無論何時使用socket-> write(「CDATA」)寫入第一個字節,此時的「C」將意味着服務器執行某些操作的命令。

我只想知道一件事,即寫入是否會分解爲服務器上的多次讀取?我知道服務器上會有一個用於讀取的緩衝區大小。但是,當寫入處於服務器的緩衝區限制內時,客戶機上的socket-> write()是否可以在服務器上的多次讀取中接收?

要清除此問題,我將給出一個示例假設服務器上的套接字的緩衝區讀取大小爲4096字節。客戶端將套接字寫入(「CDATA」)到服務器。現在有沒有可能的服務器會收到多於一個讀取?因爲我在服務器上有一個while循環:

while{ 
char str[] = socket->read(); 
// What is the coomand in the first byte 
if(str[0] == "C"){ 
    // Do something 
} 
} 

如果由客戶端發送的數據在一個以上的讀取(即使客戶端發送它在一個寫)收到我的協議設計將失敗。

+3

由於您對大寫單詞的使用不當,我現在試圖解碼您的消息可能包含的任何幫助。不要擔心人工登錄名是否正確 – Wug

回答

1

現在有沒有可能,服務器將收到多於一個讀取?

是的,TCP/IP可以以任何喜歡的方式對消息進行分段。 TCP是一個有狀態的流協議:你保證你放在一端的字節會以相同的順序從另一端出來。 IP是無連接和基於數據報的。由於承載基於IP的TCP的性質,可能會出現數據包在傳輸中被拆分,合併或處理的情況。

您應該找到一種方法來清理您的程序,以避免錯綜複雜的網絡通信。您可以:

  • 使用數據報協議(如UDP)(你輸在訂單獲取數據被髮送的保證,而丟棄的數據包成爲可能,以及當今的網絡相當強勁,這通常不是。一個問題)。

    [DATAGRAM (size specified in datagram header)] 
    
  • 總是從網絡讀取一個固定大小的塊

    [DATA - block of data of some fixed size] 
    
  • 包括所述輸入數據的大小作爲附接至前

    [LENGTH - 4 byte integer][DATA - block of data of size LENGTH] 
    
  • 使用某些標頭用於指示數據結束的分隔符,並繼續閱讀,直至獲得它

    [DATA - indeterminately sized data][DELIMITER - end-of-data control sequence] 
    

很可能您可以使用庫方法來執行此行爲,因爲您只需要很少的代碼。

+0

例如:HTTP是換行符分隔的。SFTP是一種數據報協議。 FTP,我認爲,使用一個標題。 Minecraft使用標題。 SSH,telnet和其他字符shell協議基本上由每個字符分隔。 – Wug

+0

「將傳入數據的大小作爲附加在前面的標題」這正是這裏的問題先生。假設我包含4個字節的頭部和4096個字節的數據,但數據在服務器上以2個字節和4098個字節接收。在這種情況下我該怎麼辦? OR將以4字節和4096字節的連續性接收數據。 – user1066991

+0

您可以使用'read'讀取指定大小的數據。我無法找到任何支持使用'socket-> read()'的文檔,我找到的所有文檔都帶有參數。如果你有一個包裝類或其他東西,發佈它。無論如何,您可以使用'QByteArray QTcpSocket :: read(qint64 maxlen)'從流中讀取指定數量的字節。 – Wug