tmb*_*gmn 1 python sockets buffer asyncore
我是Python的新手(虽然我已经用Java编程多年了),我正在开发一个简单的基于套接字的网络应用程序(只是为了好玩).我的想法是我的代码连接到远程TCP端点,然后侦听从服务器推送到客户端的任何数据,并对此执行一些解析.
从服务器 - >客户端推送的数据是UTF-8编码文本,每行由CRLF(\x0D\x0A)分隔.您可能已经猜到:想法是客户端连接到服务器(直到被用户取消),然后在它们进入时读取和解析这些行.
我已经设法让这个工作,但是,我不确定我这样做是否正确.因此,我的实际问题(代码要遵循):
asyncore?目前,数据正在被读取和缓冲,如下所示:
def handle_read(self):
self.ibuffer = b""
while True:
self.ibuffer += self.recv(self.buffer_size)
if ByteUtils.ends_with_crlf(self.ibuffer):
self.logger.debug("Got full line including CRLF")
break
else:
self.logger.debug("Buffer not full yet (%s)", self.ibuffer)
self.logger.debug("Filled up the buffer with line")
print(str(self.ibuffer, encoding="UTF-8"))
Run Code Online (Sandbox Code Playgroud)
该ByteUtils.ends_with_crlf函数只是检查缓冲区的最后两个字节\x0D\x0A.第一个问题是主要问题(答案是基于此),但任何其他想法/提示都表示赞赏.谢谢.
TCP是一个流,并不保证您的缓冲区不会包含一条消息的结尾和下一条消息的开头.因此,在缓冲区末尾检查\n\r \n将无法在所有情况下按预期工作.您必须检查流中的每个字节.
并且,我强烈建议您使用Twisted而不是asyncore.像这样的东西(从内存,可能无法开箱即用):
from twisted.internet import reactor, protocol
from twisted.protocols.basic import LineReceiver
class MyHandler(LineReceiver):
def lineReceived(self, line):
print "Got line:", line
f = protocol.ClientFactory()
f.protocol = MyHandler
reactor.connectTCP("127.0.0.1", 4711, f)
reactor.run()
Run Code Online (Sandbox Code Playgroud)
它甚至更简单 - 看看asynchat及其set_terminator方法(以及该模块中的其他有用的花絮). 扭曲的数量级更丰富,更强大,但是,对于足够简单的任务,asyncore和asynchat(设计用于平滑互操作)确实非常简单易用,因为您已经开始观察了.