有没有办法不从UDP套接字缓冲数据

时间:2014-05-27 18:49:11

标签: python sockets synchronization udp timing

我正在使用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     五 ...

我应该做些什么来获得我想要的行为?

编辑:要扩展问题,我会在每次客户收到勾选时记录一个事件。我想记录以下序列:[触发,暂停,触发,暂停]但是,由于一些滴答被缓冲,我得到:[触发,暂停,触发,触发,触发],使我的事件在彼此接近时间。

1 个答案:

答案 0 :(得分:1)

套接字缓冲区在内核中,而不在python中。每当数据包进入时,它都会被放入此缓冲区,直到用户空间从内核中读取它为止。您可以使用setsockopt来更改缓冲区的大小,但这是一个字节大小而不是数据包。并且将它设置为小是不太好的,因为如果在机器上接收到数据包并且套接字缓冲区已满,则新数据包将被丢弃。

更好的方法是保持套接字缓冲区不变,但将套接字设置为非阻塞,然后调用recvfrom直到你不再获取数据 - 然后处理你读过的最后一个数据包。