我正在尝试创建某种客户端监视器,例如终端,以通过以太网从串行设备接收数据。我正在尝试使用带有 python 的套接字,但是当我创建连接时出现问题。我应该只从服务器收到一条消息,我收到了整条消息,但分为两个数据包,如下所示:
预期消息:
b'-- VOID MESSAGE--'
收到消息:
b'-- VOID'
b' MESSAGE--'
不知道是缓冲区大小、解码还是其他函数的问题
import socket
TCP_IP = '192.168.#.#'
TCP_PORT = ###
BUFFER_SIZE = 1024
data1=' '
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
while(1):
data = s.recv(BUFFER_SIZE)
print(data.decode('ASCII'))
s.close()
我已经尝试过一些编解码器选项,例如 UTF-8、UTF-16 和 ASCII,但我仍然得到相同的结果。
这个函数帮助我解决了问题。
while(1):
cadena += s.recv(1)
if (((cadena)[i])=='\n'):
print(cadena.decode('ASCII'))
cadena=b''
i=-1
i+=1
最佳答案
如前所述 - 这就是套接字的工作原理。 发送的数据可以分成 block 。所以如果你想确定你已经收到了发送的整个消息,你需要实现某种协议(protocol),其中的一部分将包含你的消息的长度。例如:
- 前四个字节(整数)表示消息的长度
- 其他字节-消息的内容
在这种情况下,发送消息的算法如下所示:
- 计算消息的长度
- 写入带有消息长度的套接字整数(4字节)
- 写入消息的socket内容
和阅读算法:
- 从套接字读取字节并将读取数据写入累加器缓冲区
- 从缓冲区读取前四个字节作为整数——这将是消息长度
- 检查缓冲区长度是否大于或等于“{message length} + 4”
- 如果它随后读取了所需的字节数,这将是已发送的消息。
- 从缓冲区中删除第一个“{message length} + 4”字节
- 从第二点开始重复
- 如果字节数不足以读取消息内容,则从第一点开始重复。
关于python - 套接字碎片接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57826357/