Python 保存UDP流中每N个数据包

Python 保存UDP流中每N个数据包,python,udp,python-multithreading,mpeg2-ts,Python,Udp,Python Multithreading,Mpeg2 Ts,我正在解析从UAV发送到UDP端口的MPEG-TS视频流中嵌入的KLV数据,以用于实时地图。目前我每秒收到25个数据包(与视频帧速率有关),可以保存所有这些数据,但我只想每秒保存一次数据。每40毫秒就太多了。我尝试使用线程来运行2个函数。一个用于获取数据并写入全局变量,另一个用于每秒读取该变量并打印/保存 #setup code (UDP socket etc) #global variable for KLV metadata metadata = {} #Function to pars

我正在解析从UAV发送到UDP端口的MPEG-TS视频流中嵌入的KLV数据,以用于实时地图。目前我每秒收到25个数据包(与视频帧速率有关),可以保存所有这些数据,但我只想每秒保存一次数据。每40毫秒就太多了。我尝试使用线程来运行2个函数。一个用于获取数据并写入全局变量,另一个用于每秒读取该变量并打印/保存

#setup code (UDP socket etc)

#global variable for KLV metadata
metadata = {}

#Function to parse KLV data from UDP Stream using klvdata module
def getData():
    while True:
        data, address = sock.recvfrom(2048)
        for packet in klvdata.StreamParser(data):
            global metadata
            metadata=packet.MetadataList()
           
           
#Prints selected keys at 1 sec intervals. Add more keys as required           
def printData():
     while True:
        global metadata
        time.sleep(1)
        
        long = round(float(metadata[14][3]),6)
        print(f"Sensor Longitude: {long}")
        
        lat = round(float(metadata[13][3]),6)
        print(f"Sensor Latitude: {lat}")



if __name__ == '__main__':
    t1 = Thread(target=getData)
    t1.start()
            
    t2 = Thread(target=printData)
    t2.start()
这取得了喜忧参半的成功。如果UDP流没有运行,我会得到一个键错误,因为dict是空的,无论是否有新数据,printData func中的while循环都是无限的。我理解这两种错误以及它们发生的原因。我想知道的是,是否有比我现在走的路更好的方法来做到这一点


谢谢

我无法测试它,但我会使用
metadata=None
如果元数据不是None:
来控制是否有新数据

metadata = None

def getData():
    global metadata # need it because you assign value to variable
    
    while True:
        data, address = sock.recvfrom(2048)
        for packet in klvdata.StreamParser(data):
            metadata = packet.MetadataList()            
        # end of data
        metadata = None            
           
def printData():
    #global metadata # no need it when you only read data from variable
    
    while True:
        time.sleep(1)

        if metadata is not None:         
            long = round(float(metadata[14][3]), 6)
            print(f"Sensor Longitude: {long}")
        
            lat = round(float(metadata[13][3]), 6)
            print(f"Sensor Latitude: {lat}")

但我不确定这是否需要锁定
元数据
,因为一个进程可能会读取
long
lat
,而另一个进程可能会分配
元数据=None
,这可能会造成问题。

到目前为止,这段代码仍然有效,但我将测试更多

#global variable for KLV metadata
metadata = None

#Function to parse KLV data from UDP Stream using klvdata module
def getData():
    global metadata
    while True:
        data, address = sock.recvfrom(2048)
        for packet in klvdata.StreamParser(data):
            metadata=packet.MetadataList()
           
           
           
#Prints selected keys at 1 sec intervals. Add more keys as required           
def printData():
    global metadata
    while True:
        time.sleep(1)
        if metadata is not None:
            long = round(float(metadata[14][3]),6)
            print(f"Sensor Longitude: {long}")
        
            lat = round(float(metadata[13][3]),6)
            print(f"Sensor Latitude: {lat}")

            metadata = None

全局
放在函数开头有一个很好的规则。您必须在文件中只使用一次它-您不必在
中多次使用它,而
-loop如果您遇到kye错误,那么您可以使用
try/except
捕获它,或者使用
if key in dict:
仅当dict中有键时才运行代码。如果您有list,则可以使用
if len(list)>索引:
在存在时运行代码
列出[索引]
如果您想在没有新数据时停止写入,那么可以使用一些变量来控制它-如
如果新数据为真:…
或使用number或date\u time来控制是否有新数据<代码>如果新编号>旧编号:。。。写入数据;旧编号=新编号
在开始时,我会使用
元数据=无
,然后我可以检查
元数据是否为无:。。。写入数据…
。当没有新数据时,我会再次设置
metadata=None
以停止写入相同的数据。谢谢您的输入。最后,我稍微调整了代码,并在printData函数的末尾设置metadata=none,而不是在getData函数中。我还必须恢复
全局元数据
。您可以在答案中描述所有更改,然后将其标记为已接受。