我使用Python的socket.socket類構建一個客戶端,該類接收大小不同的數據(通常在500到5,000字節之間,但理論上客戶端套接字可能接收到500,000字節)。我還在編寫將與此客戶端套接字進行通信的服務器。爲什麼要在套接字的'recv'方法上設置一個保守的最大字節大小?
我很好奇地想知道,什麼是設置最大字節大小的風險,我可以相信我絕不會超過如:
socket.recv(1000000)
即使我知道這遠遠大於99%的套接字實際使用情況。
我使用Python的socket.socket類構建一個客戶端,該類接收大小不同的數據(通常在500到5,000字節之間,但理論上客戶端套接字可能接收到500,000字節)。我還在編寫將與此客戶端套接字進行通信的服務器。爲什麼要在套接字的'recv'方法上設置一個保守的最大字節大小?
我很好奇地想知道,什麼是設置最大字節大小的風險,我可以相信我絕不會超過如:
socket.recv(1000000)
即使我知道這遠遠大於99%的套接字實際使用情況。
你所做的只是浪費史詩般的記憶。
如果你以最快的速度閱讀,你將永遠不會得到比路徑MTU,這是通常在1500個字節,當然以千字節,兆沒有測量更多。
如果你沒有在最高速度閱讀,已經有一個套接字接收緩衝區的內核,其大小介於根據你的平臺的範圍內8-64k,並通過TCP的操作是完全recv()不可能提供比該緩衝區更多的數據。
套接字不按您認爲的方式工作。 socket.recv(N)
並不意味着您將返回N個字節。這意味着您將返回最多 N個字節。這與發件人試圖發送給您的字節數無關。 TCP是流導向。這意味着您將按照發件人發送的順序獲取發件人發送給您的字節。但是你不會得到和發送數據時一樣的「消息」邊界。
你有寫你的代碼可以多次調用recv因爲你知道,socket.recv(1000000)
會返回一個字節給你。而現在,只要你多次調用它,與收到的消息大小相比,你不必考慮參數的大小。正如其他海報所說的,你想傳遞一個與堆棧其他某個層次上最大緩衝區大小相當的值。其中一個緩衝區(路徑MTU)可能在1500左右(但可以更大或更小)。但是內核的TCP/IP堆棧中的本地接收緩衝區較大,大概在64k或128k左右。這些可能接近合理的價值。
雖然我建議不要在這個級別寫網絡代碼。它已經完成 - 或多或少地死亡。重點放在應用程序的新穎部分,重新使用一些爲您處理這些細節的現有庫可能會更好。我建議Twisted。
路徑MTU通常*在1500字節以下,但並非總是如此。例如,在環回設備上讀取時,它通常在16384字節左右。非以太網LAN也可能具有更高的MTU。 –