python - 为什么在socketserver例子中只读取了1024字节

标签 python socketserver

我正在阅读 https://docs.python.org/2/library/socketserver.html 的 python socketserver 文档示例

为什么在 handle 方法内 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()

最佳答案

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

原因是,即使源通过网络发送了 300 字节,数据也有可能作为 200 字节和 100 字节的两个独立 block 到达接收方。

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

无法在 Python 级别实现“读取直到消息结束”,因为 send/recv 函数只是 TCP 套接字的包装器接口(interface),这是一个接口(interface),没有消息边界(因此无法知道是否已从源接收到“所有”数据)。

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

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

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

注意:Python 文档确实对recv 的行为具有误导性,希望很快得到修复。

关于python - 为什么在socketserver例子中只读取了1024字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29815020/

相关文章:

python - 将变量发送到python中的TCPHandler

Python - 如何从扩展命名空间导入父包

python - 需要黑白棋游戏说明

python - 如何在 Python 中测试命令行应用程序?

python - Django:覆盖子模型中的字段标签或帮助文本

linux - 如何知道远程端是否使用发送系统调用关闭套接字?

.net - TcpListener:如何监听所有接口(interface)上的特定端口?

扩展 SocketServer.TCPServer 时出现 Python "instance has no attribute"错误

python - 使用 Excel 工作表中的数据替换数据框中的值

Python - BaseHTTPServer.HTTPServer 并发和线程