我正在尝试将数据从一个树莓派(4)发送到另一个树莓派(0 w)(我包括设备,因为 w 0 不是功率最高的设备,运行桌面时有点慢,但是我不确定这是否是问题)。转移通常有效,但每隔一段时间,我就会丢失一条消息。我想我可以添加一个额外的步骤来确保消息通过并在没有通过时再次请求它(例如,将每条消息粘贴在 while 循环中以比较计数器编号),但我不确定是否有更好的方法。下面出现了一些虚拟代码来说明问题。
客户端(树莓派 4)
#client
import socket
import time
import pickle
import random
HOST = '192.168.1.37'
PORT = 2031
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
counter = 0
while True:
counter += 1
message = ['note_off', 21, counter, time.time()]
message_2 = pickle.dumps(message)
print(message)
s.send(message_2)
time.sleep(random.random() / 10)
服务器(树莓派 0 w)
# server
import socket
import pickle
import time
import threading
HOST = '192.168.1.37'
PORT = 2031
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
global stop
stop = False
def testa():
counter = 0
conn, addr = s.accept()
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
print('Connected by', addr)
try:
while True and not stop:
message_2 = conn.recv(1024)
message = pickle.loads(message_2)
if message:
counter += 1
print('counter = {}, message = {}'.format(counter, message))
s.close()
except:
print('closing')
s.close()
try:
print('creating thread')
test_thread = threading.Thread(target=testa)
print('starting thread')
test_thread.start()
print('thread started')
except:
s.close()
stop = True
所以在客户端代码中,我正在运行一个计数器并将其包含在消息的一部分中,并在另一个程序中运行一个重复的计数器,以便我们进行比较。我正在打印输出以进行验证。
counter = 1, message = ['note_off', 21, 1, 1585259341.171993]
counter = 2, message = ['note_off', 21, 2, 1585259341.2157793]
...
counter = 27, message = ['note_off', 21, 27, 1585259342.608451]
counter = 28, message = ['note_off', 21, 28, 1585259342.6267097]
counter = 29, message = ['note_off', 21, 31, 1585259342.739835]
counter = 30, message = ['note_off', 21, 32, 1585259342.813044]
counter = 31, message = ['note_off', 21, 33, 1585259342.8884292]
...
counter = 230, message = ['note_off', 21, 267, 1585259354.8655927]
counter = 231, message = ['note_off', 21, 268, 1585259354.9502656]
counter = 232, message = ['note_off', 21, 269, 1585259354.999945]
计数器,然后message
应该匹配的第三个元素,它们匹配了一段时间,但随后消息开始被丢弃。
注意:当我编写这个时,我意识到我没有在客户端代码中设置套接字选项。我在那里使用该选项再次运行它,并得到相同的结果(丢失消息)。不确定这是否相关,或者我是否需要那里的代码,但我想我应该提到它。
解决方案正如评论中所指出的,这是由于我误解了流的工作原理(我当时认为这是一个消息流,而实际上它是一个字节流)。就我而言,由于我确切知道要发送的对象有多大,我可以设置参数 forrecv
以准确查找发送的字节数(有更优雅的解决方案,但这一个适用于我的情况)。