在找到分隔符之前,如何使用 TCP Python 套接字正确接收数据?
How can I properly receive data with a TCP Python socket until a delimiter is found?
我从一个没有预先指定数据长度的源 (Twitch IRC) 接收数据,并且它从不发送一致数量的数据。此源使用“\r\n”作为其分隔符,我想接收数据直到找到此分隔符,停止接收以处理接收到的数据,然后继续接收。我已经尝试了一些我想出的解决方案:
delimiter = "\r\n"
buffer = ""
while True:
received = socket.recv(1).decode("utf-8", "ignore")
buffer += received
if buffer.endswith(delimiter):
process_data(buffer)
buffer = ""
这个解决方案并不理想,因为“received”在只接收一个字节时通常是一个空字符串,这会在我的应用程序中触发一个错误处理程序(因为 Python 在连接时不会引发异常在 recv() 调用期间下降,它只是 returns 一个空字符串)。
delimiter = "\r\n"
buffer = ""
while True:
received = socket.recv(2048).decode("utf-8", "ignore")
received_messages = received.split(delimiter)
for i in received_messages[:-1]:
process_data(data)
这不是一个好的解决方案,因为 split() 删除了分隔符,这导致我无法知道列表中的最后一个元素是否是完整的消息。
在 Python TCP 套接字中找到定界符之前接收数据的最佳方式是什么?我正在寻找的功能类似于 Boost 的 boost::asio::read_until().
您可以缓冲数据并在找到分隔符后提取整个消息。示例:
server.py
from socket import *
class Buffer:
def __init__(self,sock):
self.sock = sock
self.buffer = b''
def get_line(self):
while b'\r\n' not in self.buffer:
data = self.sock.recv(1024)
if not data: # socket closed
return None
self.buffer += data
line,sep,self.buffer = self.buffer.partition(b'\r\n')
return line.decode()
s = socket()
s.bind(('',5000))
s.listen()
while True:
c,a = s.accept()
with c:
print('Connected:',a)
b = Buffer(c)
while True:
line = b.get_line()
if line is None:
break
print('line:',line)
print('Disconnected:',a)
client.py
from socket import *
s = socket()
s.connect(('localhost',5000))
s.sendall(b'a partial')
s.sendall(b' line\r\nand another')
s.sendall(b' line\r\n')
s.close()
输出:
Connected: ('127.0.0.1', 59552)
line: a partial line
line: and another line
Disconnected: ('127.0.0.1', 59552)
我从一个没有预先指定数据长度的源 (Twitch IRC) 接收数据,并且它从不发送一致数量的数据。此源使用“\r\n”作为其分隔符,我想接收数据直到找到此分隔符,停止接收以处理接收到的数据,然后继续接收。我已经尝试了一些我想出的解决方案:
delimiter = "\r\n"
buffer = ""
while True:
received = socket.recv(1).decode("utf-8", "ignore")
buffer += received
if buffer.endswith(delimiter):
process_data(buffer)
buffer = ""
这个解决方案并不理想,因为“received”在只接收一个字节时通常是一个空字符串,这会在我的应用程序中触发一个错误处理程序(因为 Python 在连接时不会引发异常在 recv() 调用期间下降,它只是 returns 一个空字符串)。
delimiter = "\r\n"
buffer = ""
while True:
received = socket.recv(2048).decode("utf-8", "ignore")
received_messages = received.split(delimiter)
for i in received_messages[:-1]:
process_data(data)
这不是一个好的解决方案,因为 split() 删除了分隔符,这导致我无法知道列表中的最后一个元素是否是完整的消息。
在 Python TCP 套接字中找到定界符之前接收数据的最佳方式是什么?我正在寻找的功能类似于 Boost 的 boost::asio::read_until().
您可以缓冲数据并在找到分隔符后提取整个消息。示例:
server.py
from socket import *
class Buffer:
def __init__(self,sock):
self.sock = sock
self.buffer = b''
def get_line(self):
while b'\r\n' not in self.buffer:
data = self.sock.recv(1024)
if not data: # socket closed
return None
self.buffer += data
line,sep,self.buffer = self.buffer.partition(b'\r\n')
return line.decode()
s = socket()
s.bind(('',5000))
s.listen()
while True:
c,a = s.accept()
with c:
print('Connected:',a)
b = Buffer(c)
while True:
line = b.get_line()
if line is None:
break
print('line:',line)
print('Disconnected:',a)
client.py
from socket import *
s = socket()
s.connect(('localhost',5000))
s.sendall(b'a partial')
s.sendall(b' line\r\nand another')
s.sendall(b' line\r\n')
s.close()
输出:
Connected: ('127.0.0.1', 59552)
line: a partial line
line: and another line
Disconnected: ('127.0.0.1', 59552)