我正在阅读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()
答案 0 :(得分:3)
从套接字读取时,总是需要进行循环。
原因是即使发送的源通过网络说300字节,例如数据也可能作为两个单独的200字节和100字节的块到达接收器。
因此,当您为recv
指定缓冲区大小时,您只需说明您愿意处理的最大金额,但返回的实际数据量可能会更小。
在Python级别无法实现“直到消息结束时读取”,因为send
/ recv
函数只是TCP套接字接口的包装器,而且是< strong> stream 接口,没有消息边界(因此无法知道是否已从源接收到“全部”数据)。
这也意味着在许多情况下,如果您需要使用消息进行通话,则需要添加自己的边界(或者您需要使用更高级别的基于消息的网络传输接口,如0MQ)< / p>
请注意,“阻塞模式” - 从套接字读取时 - 仅定义操作系统的网络层尚未收到数据时的行为:在这种情况下,阻塞时 - 程序将等待一个块数据的;如果非阻塞 - 它将立即返回而不等待。如果计算机已收到任何数据,则即使传递的缓冲区大小较大,recv
调用也会立即返回 - 与阻塞/非阻塞设置无关。
阻止模式并不意味着recv
调用将等待缓冲区被填充。
注意:Python文档确实误导了recv
的行为,希望很快就会修复。
答案 1 :(得分:0)
TCP套接字只是一个字节流。把它想象成阅读文件。以1024字节的块读取文件是否更好?这取决于内容。通常,套接字(如文件)被缓冲,只提取完整的项目(行,记录,任何适当的)。这取决于实施者。
在这种情况下,最多读取1024。如果发送的金额较大,则会被分解。由于此代码中没有已定义的消息边界,因此无关紧要。如果您只想接收完整的行,请实现一个循环来读取数据,直到确定了消息边界。也许读到检测到回车并处理完整的文本行。