【问题标题】:Python socket recv() doesn't get every message if send too fast如果发送太快,Python socket recv() 不会收到每条消息
【发布时间】:2017-02-17 07:13:44
【问题描述】:

我通过套接字将鼠标坐标从 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()

【问题讨论】:

    标签: python sockets


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 你是对的!我只是快速检查了一下,结果发现我只阅读了部分传递的消息。正如您提到的,一些消息被连接起来,我没有正确阅读它们。 'pickle.loads' 没有抛出任何异常,所以这欺骗了我。现在我需要弄清楚如何阅读它们。
    • OP 可以尝试socket.sendall() 以确保发送所有数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 2011-05-09
    • 2022-11-28
    • 2016-01-30
    • 1970-01-01
    • 2019-11-08
    相关资源
    最近更新 更多