我正在使用UDP将服务器发送时钟节拍作为多播消息。服务器的代码是:
import socket
import struct
import sys
import time
multicast_group = ('224.3.29.71', 10000)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(0.2)
ttl = struct.pack('B', 255)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
try:
i = 0
while True:
#print "tick"
sent = sock.sendto(str(i), multicast_group)
i += 1
time.sleep(1.0/25.0)
finally:
print "closing socket"
sock.close()
我希望客户端在收到勾选时执行某些操作,但跳过它在处理时错过的滴答。
例如,如果客户端收到#1号码并且在执行处理时错过了#2和#3号滴答,我希望#4号码成为下一个收到的消息。
然而,似乎由于套接字是缓冲的,它有时会收到它应该跳过的标记。
以下是客户端的代码:
import socket
import struct
import sys
import time
multicast_group = '224.3.29.71'
server_address = ('', 10000)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(server_address)
sock.setblocking(0)
group = socket.inet_aton(multicast_group)
mreq = struct.pack('4sL', group, socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
while True:
try:
data, address = sock.recvfrom(1024)
print data
time.sleep(1) #simulate processing
except socket.error:
pass
客户端输出: 1 2 3 4 五 ...
我应该做些什么来获得我想要的行为?
编辑:要扩展问题,我会在每次客户收到勾选时记录一个事件。我想记录以下序列:[触发,暂停,触发,暂停]但是,由于一些滴答被缓冲,我得到:[触发,暂停,触发,触发,触发],使我的事件在彼此接近时间。
答案 0 :(得分:1)
套接字缓冲区在内核中,而不在python中。每当数据包进入时,它都会被放入此缓冲区,直到用户空间从内核中读取它为止。您可以使用setsockopt来更改缓冲区的大小,但这是一个字节大小而不是数据包。并且将它设置为小是不太好的,因为如果在机器上接收到数据包并且套接字缓冲区已满,则新数据包将被丢弃。
更好的方法是保持套接字缓冲区不变,但将套接字设置为非阻塞,然后调用recvfrom直到你不再获取数据 - 然后处理你读过的最后一个数据包。