为什么在socketserver示例中只读取1024个字节

时间:2015-04-23 06:05:48

标签: python socketserver

我正在阅读https://docs.python.org/2/library/socketserver.html

的python socketserver的文档示例

为什么在句柄方法内的行self.request.recv(1024)中将大小指定为1024。如果客户端发送的数据超过1024字节会发生什么? 在socket为空之前,有一个循环读取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()

2 个答案:

答案 0 :(得分:3)

从套接字读取时,总是需要进行循环。

原因是即使发送的源通过网络说300字节,例如数据也可能作为两个单独的200字节和100字节的块到达接收器。

因此,当您为recv指定缓冲区大小时,您只需说明您愿意处理的最大金额,但返回的实际数据量可能会更小。

在Python级别无法实现“直到消息结束时读取”,因为send / recv函数只是TCP套接字接口的包装器,而且是< strong> stream 接口,没有消息边界(因此无法知道是否已从源接收到“全部”数据)。

这也意味着在许多情况下,如果您需要使用消息进行通话,则需要添加自己的边界(或者您需要使用更高级别的基于消息的网络传输接口,如0MQ)< / p>

请注意,“阻塞模式” - 从套接字读取时 - 仅定义操作系统的网络层尚未收到数据时的行为:在这种情况下,阻塞时 - 程序将等待一个块数据的;如果非阻塞 - 它将立即返回而不等待。如果计算机已收到任何数据,则即使传递的缓冲区大小较大,recv调用也会立即返回 - 与阻塞/非阻塞设置无关。

阻止模式并不意味着recv调用将等待缓冲区被填充。

注意:Python文档确实误导了recv的行为,希望很快就会修复。

答案 1 :(得分:0)

TCP套接字只是一个字节流。把它想象成阅读文件。以1024字节的块读取文件是否更好?这取决于内容。通常,套接字(如文件)被缓冲,只提取完整的项目(行,记录,任何适当的)。这取决于实施者。

在这种情况下,最多读取1024。如果发送的金额较大,则会被分解。由于此代码中没有已定义的消息边界,因此无关紧要。如果您只想接收完整的行,请实现一个循环来读取数据,直到确定了消息边界。也许读到检测到回车并处理完整的文本行。