2015-04-23 56 views
3

我通過爲蟒SocketServer的文檔的例子讀數https://docs.python.org/2/library/socketserver.html爲什麼只有1024個字節中的SocketServer例如

讀爲什麼在線路self.request.recv(1024)內側手柄方法指定爲1024的大小。如果客戶端發送的數據超過1024字節會發生什麼情況? 有一個循環讀取1024個字節,直到套接字爲空爲止更好嗎?我在這裏複製了示例:

import SocketServer 

class MyTCPHandler(SocketServer.BaseRequestHandler): 
    """ 
    The RequestHandler class for our server. 

    It is instantiated once per connection to the server, and must 
    override the handle() method to implement communication to the 
    client. 
    """ 

    def handle(self): 
     # self.request is the TCP socket connected to the client 
     self.data = self.request.recv(1024).strip() # why only 1024 bytes ? 
     print "{} wrote:".format(self.client_address[0]) 
     print self.data 
     # just send back the same data, but upper-cased 
     self.request.sendall(self.data.upper()) 

if __name__ == "__main__": 
    HOST, PORT = "localhost", 9999 

    # Create the server, binding to localhost on port 9999 
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler) 

    # Activate the server; this will keep running until you 
    # interrupt the program with Ctrl-C 
    server.serve_forever() 

回答

0

TCP套接字只是一個字節流。把它想象爲閱讀文件。以1024字節塊讀取文件會更好嗎?這取決於內容。像文件一樣,套接字通常被緩衝,只有完整的項目(行,記錄,任何合適的)被提取。這取決於實施者。

在這種情況下,最多讀取1024。如果發送的金額較大,則會被分解。由於在此代碼中沒有定義的消息邊界,所以它並不重要。如果您只關注接收完整行,請實施循環以讀取數據,直至確定​​消息邊界。也許閱讀直到檢測到回車並處理完整的文本行。

+0

如果發送的數量較大,它將被分解,在這種情況下,只有前1024個字節將被讀取,因爲沒有循環來讀取更多數據? –

3

從套接字讀取時,總是需要做一個循環。

原因是,即使源發送通過網絡說300字節,例如數據將作爲兩個獨立的200字節和100字節的塊到達接收器是可能的。

出於這個原因,當你指定一個緩衝區大小爲recv你只能說你願意處理最大量,但返回可能會更小的實際數據量。

沒有辦法實施「讀,直到該消息的末端」在Python層面因爲send/recv功能是簡單地將TCP套接字接口的包裝,這是一個接口,無需消息邊界(因此無法知道是否從源收到「全部」數據)。

這也意味着,在許多情況下,您將需要添加自己的邊界,如果你需要使用郵件交談(或者你需要使用一個更高級別的基於消息的網絡傳輸接口像0MQ

請注意,「阻塞模式」 - 從套接字讀取時 - 僅定義了操作系統的網絡層沒有收到數據時的行爲:在這種情況下,阻塞時 - 程序將等待大塊數據;如果不是阻塞,它會立即返回而不用等待。如果計算機已經收到任何數據,則即使傳遞的緩衝區大小較大,recv調用也會立即返回 - 與阻止/非阻止設置無關。

阻塞模式並不意味着recv調用將等待緩衝區被填充。

注意:Python文檔確實誤導了recv的行爲,希望很快會得到解決。

+0

這是否假設非阻塞模式?Python的'socket'模塊文檔狀態*最初所有套接字都處於阻塞模式* ... *處於阻塞模式,阻塞直到它們可以繼續*。 – cdarke

+0

@cdarke:當存在**任意數量的數據**時,可以繼續執行'recv'調用,而不是在填充緩衝區時。通過循環實現'recvall'(帶有強制大小參數)當然是微不足道的。 – 6502

+0

@cdarke所以在這個特定的例子中,只有前1024個(或更少)的字節被讀取,並且如果客戶端發送的數據很大,它會被忽略嗎? –

相關問題