2017-06-17 90 views
2

我正在閱讀一本網絡書籍,並從我已閱讀的TCP協議中瞭解到,它確保數據將被髮送。我想寫一些代碼來做文件傳輸。來說說這個之前,我也是在Python文檔閱讀這樣一段話:TCP能真正保證交付嗎?

「應用程序負責檢查所有數據已經​​ 發送;如果只有部分數據被傳送,應用程序需要 嘗試交付剩餘的數據「

這似乎與我在網絡書中讀到的內容相矛盾。上面的段落說應用程序負責丟失的數據。

我可能誤解,所以我要問一些問題:

1,如果我要檢查數據發送,那麼爲什麼要使用TCP?

2我在網絡書中讀到TCP做數學計算以確保數據在那裏。那爲什麼不使用TCP浪費時間?

3- python文檔沒有指定緩衝區大小。一次發送緩衝區的最大大小是多少?

4我在網絡書中讀到,如果服務器知道客戶端可以接收它,它可以發送的數據量增加 。可以這樣更改 緩衝區的大小是否超過最大值?

這是到目前爲止我的代碼的嘗試:

Server代碼:

import socket 
s = socket.socket() 
host = socket.gethostname() 
port = 3000 
s.bind((host,port)) 
s.listen(1) 
c,addr = s.accept() 
with open("Filetosend","rb") as File: 
    data= File.read(1024) 
    while data: 
     c.send(data) 
     data = File.read(1024) 
s.close() 

客戶端代碼:

import socket 
s= socket.socket() 
host = socket.gethostname() 
port = 3000 
s.connect((host,port)) 
with open("Filetowrite","wb") as File: 
    data = s.recv(1024) 
    while data: 
     File.write(data) 
     data = s.recv(1024) 
s.close() 

回答

5

TCP試圖保證,如果數據傳遞,這是正確的,爲了。它使用校驗和來確保數據不被破壞,並使用序列號來確保數據按順序傳遞並且沒有間隙。它使用確認,因此發件人會知道已收到數據。

但是假設傳輸過程中出現網絡故障。如果發生在收到數據段後,但在確認被髮回之前,發件人將不知道數據已收到。發件人將不斷嘗試重新發送數據,並最終超時並嚮應用程序報告錯誤。

大多數TCP API不允許應用程序準確找出錯誤發生在通信的哪個位置。如果您發送了一個兆字節併發生錯誤,那麼可能在一開始就發生了,幾乎沒有發送任何內容,或者在最後發送大部分數據時發生。在發送所有數據後甚至可能發生 - 也許只是最後一個ACK丟失了。

此外,系統調用write()通常只是將數據放入內核緩衝區。它不會等待數據發送到網絡,也不會等待接收方確認。

即使您成功關閉了連接,也無法完全確定。關閉連接時,發件人會向收件人發送一條消息,告知他們已完成發送數據。但關閉連接只是在網絡堆棧中排隊,它不會等待其他系統確認它。

這就是爲什麼應用程序協議在基本TCP協議之上有其自己的確認級別的原因。例如,在SMTP協議中,客戶端發送消息內容,後跟帶有.的行以指示結束,然後等待服務器發回響應代碼,指示消息已成功接收並且正在傳遞或排隊。 TCP的檢查可確保如果您收到此響應,郵件內容將完整發送。

關於任何協議保證完美傳遞所有消息的一般能力,您應該閱讀關於Two Generals' Problem.無論您做什麼,都無法驗證任何通信中所有消息的傳遞,因爲唯一的方法是確認最後發送的消息是通過發送另一條消息作爲回覆,現在即回覆是最後一條消息,需要確認。

+0

值得一提的是系統write()調用的行爲,它不保證將發送整個緩衝區。我有強烈的感覺,提到的文件是指這一點。 – ArturFH