gpt4 book ai didi

如果发送速度太快,Python 套接字 recv() 不会收到每条消息

转载 作者:行者123 更新时间:2023-11-28 22:33:24 41 4
gpt4 key购买 nike

我通过套接字将鼠标坐标从 python 服务器发送到 python 客户端。每次在服务器上捕获鼠标移动事件时都会发送鼠标坐标,这意味着非常频繁(每秒十几个左右)。

问题是当我在不同的主机上使用 python 服务器和 python 客户端时。然后只有部分消息被传送到客户端。例如第 3 条消息已送达,4 条消息未送达,4 条消息已送达等...

当服务器和客户端在同一主机(本地主机)上时,一切都很好。

当服务器和客户端位于不同的主机上时,一切都很好,但我使用标准的 Windows Telnet 客户端而不是 python 客户端从服务器读取消息。

我注意到当我在发送的每条消息之间使用 time.sleep(0.4) 中断时,所有消息都会被传递。问题是我需要实时而不是延迟的信息。是否可以使用套接字在 Python 中实现?

下面是我使用的 python 客户端代码:

import pickle
import socket
import sys


host = '192.168.1.222'
port = 8888
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print "Faile. Error:" + str(msg[0]), "Error message : " + msg[1]
sys.exit()

mySocket = socket.socket()
mySocket.connect((host,port))

while 1:
data = mySocket.recv(1024)
if not data: break
load_data = pickle.loads(data)

print 'parametr x: ' + str(load_data[0])
print 'parametr y : ' + str(load_data[1])

mySocket.close()

最佳答案

您正在使用 TCP (SOCK_STREAM),它是一种可靠的协议(protocol)(与 UDP 相反)不会丢失任何消息,即使接收方读取数据的速度不够快。相反,TCP 会降低发送速度。
这意味着问题一定出在您的应用程序代码中。

一种可能是问题出在您的发送方,即您使用 socket.send 并且不检查您打算发送的所有字节是否真的已发送。但是需要进行此检查,因为如果操作系统的套接字缓冲区已满,socket.send 可能只会发送部分数据,如果客户端读取数据的速度不够快,就会发生这种情况。

另一种可能性是您的 socket.recv 调用接收到的数据比您的 pickle.loads 需要的多,并且其余数据被丢弃(不确定 pickle.loads 如果提供的数据过多,将抛出异常)。请注意,TCP 不是消息而是流协议(protocol),因此您可能有更多 socket.recv 将返回包含多个腌制对象的缓冲区,但您只读取了第一个。这种情况发生在网络上的可能性高于本地主机,因为默认情况下 TCP 层将尝试将多个 send 缓冲区连接到一个 TCP 数据包中,以便更好地使用连接(即更少的开销) .并且很有可能在同一个 recv 调用中接收到这些信息。通过在发送方放置一个sleep(0.4),您已经有效地关闭了这种 TCP 优化,参见 NAGLE algorithm了解详情。

因此,实现您想要的内容的正确方法是:

  • 确保所有数据都已传送到服务器,即检查 socket.send 的返回。
  • 确保打开所有收到的邮件。为此,您可能需要在 TCP 流之上添加一些消息层以找出消息边界的位置。

关于如果发送速度太快,Python 套接字 recv() 不会收到每条消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39931611/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com