【问题标题】:Why does a socket connection buffer so much data?为什么一个套接字连接会缓冲这么多数据?
【发布时间】:2021-01-09 13:56:13
【问题描述】:

我有一个程序以 10Hz 的频率发送数据。

import socket
import time


if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('127.0.0.1', 19080))

    while True:
        data = time.time()
        sock.sendto(str(data).encode(), ('127.0.0.1', 9090))
        time.sleep(0.1)

第二个程序接收数据,有延迟(1Hz):

import socket
import time


if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('127.0.0.1', 9090))

    while True:
        data = time.time()
        print(time.time(), sock.recv(100))
        time.sleep(1)

过了一会儿,输出是:

1600859111.7595737 b'1600858988.4863389'
1600859112.760249 b'1600858988.5863452'
1600859113.760647 b'1600858988.6864707'
1600859114.761207 b'1600858988.7871313'
1600859115.761991 b'1600858988.8875835'

您可以看到接收数据的时间(右)和发送数据的时间(左)有很大差异。 为什么缓冲了这么多数据,我该如何摆脱它?我想要可能的最新帧,而不是缓冲帧。

【问题讨论】:

    标签: python sockets udp buffering python-sockets


    【解决方案1】:

    将套接字设置为非阻塞模式:

    sock.setblocking(False)
    

    然后,一遍又一遍地调用sock.recv,直到你得到this error

    while True:
        try:
            msg = sock.recv(100)
            print(time.time(), msg)
        except socket.error as e:
            if e.args[0] not in (errno.EAGAIN, errno.EWOULDBLOCK):
                raise
            break
    # we get to this point when there's nothing else to receive.
    # Maybe you sleep here, or set it to blocking mode and receive again, or something.
    

    这为您提供了一个优势,即您可以读取缓冲区中的所有消息。这也意味着您将能够在缓冲区中看到最新消息。您的解决方案会导致操作系统丢弃较新的消息,直到您收到最旧的消息。

    【讨论】:

    • 感谢您的回答,但我的代码中的time.sleep() 正在模拟需要一些时间的计算,并且我不需要来自套接字的过时数据,我只想要最新的数据,所以接收所有缓冲区中的数据对我的目的没有意义。抱歉,我没有在主帖中明确提及。
    • @rozumir 接收所有数据是有意义的,这样您就可以获得最新的数据。否则,你会得到最旧的,因为操作系统会忽略较新的,因为它们不适合缓冲区。
    【解决方案2】:

    我找到了答案。我必须为输入缓冲区的大小设置套接字选项。

       sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
    

    将其设置为0,以获得最大效率。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-07
      • 2016-05-19
      • 2013-04-13
      • 1970-01-01
      • 2017-11-30
      • 1970-01-01
      • 2012-10-24
      • 2023-03-06
      相关资源
      最近更新 更多