为什么套接字连接会缓冲这么多数据?
Why does a socket connection buffer so much data?
我有一个程序以 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'
您可以看到接收数据(右)和发送数据(左)的时间差异很大。
为什么缓冲了这么多数据,我该如何摆脱它?我想要可能的最新帧,而不是缓冲的帧。
我找到了答案。我必须为输入缓冲区的大小设置套接字选项。
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
将其设置为 0
,以获得最大效率。
将套接字设置为non-blocking模式:
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.
这给您带来的好处是您将读取缓冲区中的所有消息。这也意味着您将能够在缓冲区中看到最新消息。您的解决方案会导致 OS 丢弃较新的消息,直到您收到最旧的消息。
我有一个程序以 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'
您可以看到接收数据(右)和发送数据(左)的时间差异很大。 为什么缓冲了这么多数据,我该如何摆脱它?我想要可能的最新帧,而不是缓冲的帧。
我找到了答案。我必须为输入缓冲区的大小设置套接字选项。
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
将其设置为 0
,以获得最大效率。
将套接字设置为non-blocking模式:
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.
这给您带来的好处是您将读取缓冲区中的所有消息。这也意味着您将能够在缓冲区中看到最新消息。您的解决方案会导致 OS 丢弃较新的消息,直到您收到最旧的消息。