如何在Python中过滤来自套接字的传入数据?

时间:2016-07-14 18:24:21

标签: python sockets udp

我正在为我的一个项目使用UDP套接字程序来读取来自EEG耳机的传入数据。然后我使用这些数据来控制机械臂中的伺服电机。我用来创建套接字并打印出数据的代码工作正常。

import socket
import subprocess

UDP_IP = "169.254.110.133"
UDP_PORT = 50000

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))

while True:
        (data,addr) = sock.recvfrom(1024)
        print(data)

进入的数据是来自耳机的原始EEG数据,它在终端中看起来像这样:

SourceTime 31972

TargetCode 1

ResultCode 0

Feedback 1

PauseApplication 0

CursorPosX 717

CursorPosY 2047

CursorPosZ 2047

此数据每隔几毫秒有33个不同的部分。数据总是以相同的顺序排列。对于我的代码,我只需要来自数据的一些信息(TargetCode,ResultCode和Feedback)。如何过滤掉这些部分并在我的代码中使用它们。有没有办法寻找TargetCode并复制数字?或者因为TargetCode在33个部分的流中总是24号,我可以这样提取吗?

2 个答案:

答案 0 :(得分:0)

这是一个古老的问题。您可以使用python调用在Linux套接字上应用过滤器(有关其他平台的替代方法,请参见下文):

sock.setsockopt(socket.SOL_SOCKET, SO_ATTACH_FILTER, filter)

但是我们谈论的是经过编译和解析的过滤器:

  

SO_ATTACH_FILTER的参数是sock_fprog结构,             定义于:

  struct sock_fprog {
      unsigned short  len;
      struct sock_filter *filter;
  };
     

SO_ATTACH_BPF的参数是返回的文件描述符   通过bpf(2)系统调用,并且必须引用类型为                 BPF_PROG_TYPE_SOCKET_FILTER。

     

来源:http://man7.org/linux/man-pages/man7/socket.7.html

这不容易构建,尤其是在Python上。

一些不错的选择:

  • 使用scapy的attach_filter(socket, filter, interface)函数(Linux和OSX),该函数使用tcpdump解析过滤器,然后构建编译器过滤器并将其应用于您的套接字
  • 使用scapy的内置套接字(例如安装scapy,使用sock = conf.L2socket(filter="tcp")。这是跨平台的(甚至是Windows)。有关详细信息,请访问Google)

然后您只需通过一个过滤器,例如:

host 10.0.0.1
port 80
tcp port 80 and host 10.0.0.1
host 10.0.0.1 or host 10.0.0.2 or port 80 or port 443

 所有过滤器均为BPF格式(请查看https://en.m.wikipedia.org/wiki/Berkeley_Packet_Filter

答案 1 :(得分:-1)

这可能会有所帮助。

服务器

import socket              

s = socket.socket()         
UDP_IP = "169.254.110.133"
UDP_PORT = 50000              
sock.bind((UDP_IP, UDP_PORT))        

s.listen(5)                 
while True:
   c, addr = s.accept()     
   c.send('Connected to server.')
   c.close()           

<强>客户端

import socket               
UDP_IP = "169.254.110.133"
UDP_PORT = 50000   
s = socket.socket()         
s.connect((UDP_IP,UDP_PORT))
print (s.recv(1024))
s.close