【问题标题】:Decoding tcp packets using python使用python解码tcp数据包
【发布时间】:2011-01-12 03:42:11
【问题描述】:

我正在尝试解码通过 tcp 连接接收到的数据。数据包很小,不超过 100 字节。但是,当它们很多时,我会收到一些连接在一起的数据包。有没有办法防止这种情况。我正在使用 python

我试图分离数据包,我的来源如下。包以STX字节开始,以ETX字节结束,STX后面的字节为包长度,(小于5的包长度无效)校验和为ETX之前的最后一个字节

def decode(data):
  while True:
    start = data.find(STX)
    if start == -1: #no stx in message
        pkt = ''
        data = ''
        break
    #stx found , next byte is the length
    pktlen = ord(data[1])
    #check message ends in ETX (pktken -1) or checksum invalid
    if pktlen < 5 or data[pktlen-1] != ETX or checksum_valid(data[start:pktlen]) == False:
        print "Invalid Pkt"
        data = data[start+1:]
        continue
    else:
        pkt = data[start:pktlen]
        data = data[pktlen:]
        break

return data , pkt

我是这样用的

#process reports
try:
    data = sock.recv(256) 
except: continue 
else:
    while data:
        data, pkt = decode(data) 
        if pkt:
           process(pkt)

另外,如果数据流中有多个数据包,最好将数据包作为列表集合返回还是只返回第一个数据包

我对python不是很熟悉,只会C,这个方法可以吗。任何建议将不胜感激。提前致谢

谢谢

【问题讨论】:

    标签: python string tcp decoding packets


    【解决方案1】:

    TCP 在接口级别提供数据流,而不是单个数据包。如果您想要离散的数据包,您可以使用 UDP(并自己处理丢失或乱序的数据包),或者将一些数据分隔符内联。听起来您已经这样做了,使用 STX/ETX 作为分隔符。但是,正如您所注意到的,您会在 TCP 堆栈的一个数据块中获得多条消息。

    请注意,除非您进行其他处理,否则您显示的代码中的data 不一定包含整数个消息。也就是说,最后一个 STX 很可能没有匹配的 ETX。 ETX 将在没有 STX 的下一个 data 块中。

    您可能应该从 TCP 数据流中读取单个消息并在它们出现时返回它们。

    【讨论】:

    • 感谢 mpez0,您能否详细说明您回复的最后一行。你的意思是如果我有数据说三个数据包,我应该返回(1)找到的第一个数据包和(2)数据 - 第一个数据包然后再次调用子程序,直到数据中没有剩余的数据包。谢谢
    • 是的。将来自 TCP 的读取和来自数据流的初始解析结合在一个例程中,该例程可以处理 TCP 读取之间的消息拆分。调用该例程以获取下一条消息(或者,如果您愿意,可以获取可用消息的列表)或返回没有可用消息的标志。不确定这是最好的还是典型的 Python 习语,但它会起作用。
    【解决方案2】:

    数据从何而来?与其尝试手动解码,不如使用出色的 Impacket 包:

    http://oss.coresecurity.com/projects/impacket.html

    【讨论】:

    • 我想用 Python 做这个,我需要后续处理数据
    • @mikip,访问链接... impacket 是一个 Python 解决方案。出于某种原因,您的意思是“纯 Python”吗?最好解释一下为什么……
    • Impacket is 无论如何都是纯 Python。是 pcapy 使用了 C 扩展,但这里 mikip 似乎已经完成了捕获部分。
    • 嗨彼得,看看 impacket,目前对我来说看起来太复杂了。是的,我更喜欢使用纯 python Thansk
    【解决方案3】:

    试试scapy,一个强大的交互式数据包处理程序。

    【讨论】:

    • 想用Python做这个,需要后续处理数据
    • @mikip,那么你认为“scapy”中的“py”代表什么? ;-)
    【解决方案4】:

    我会创建一个类,负责从流中解码数据包,如下所示:

    class PacketDecoder(object):
    
        STX = ...
        ETX = ...
    
        def __init__(self):
            self._stream = ''
    
        def feed(self, buffer):
            self._stream += buffer
    
        def decode(self):
            '''
            Yields packets from the current stream.
            '''
            while len(self._stream) > 2:
                end = self._stream.find(self.ETX)
                if end == -1:
                    break
    
                packet_len = ord(self._stream[1])
                packet = self._stream[:end]
                if packet_len >= 5 and check_sum_valid(packet):
                    yield packet
                self._stream = self._stream[end+1:]
    

    然后像这样使用:

    decoder = PacketDecoder()
    while True:
        data = sock.recv(256) 
        if not data:
            # handle lost connection... 
        decoder.feed(data)
        for packet in decoder.decode():
            process(packet)
    

    【讨论】:

    • 谢谢布鲁诺,我还不完全理解它,因为我是 python 新手,不熟悉生成器。然而,这是一个优雅的解决方案
    【解决方案5】:

    又好又简单...:) 诀窍在于file 对象。

    f=sock.makefile()
    while True:
      STX = f.read(1)
      pktlen = f.read(1)
      wholePacket = STX + pktlen + f.read(ord(pktlen)-2)
      doSomethingWithPacket(wholePacket)
    

    就是这样!(使用 TCP 时也无需检查校验和。)

    这是一个更“强大”(?)的版本(它使用 STX 和校验和):

    f=sock.makefile()
    while True:
      while f.read(1)!=STX:
        continue
      pktlen = f.read(1)
      wholePacket = STX + pktlen + f.read(ord(pktlen)-2)
      if checksum_valid(wholePacket):
        doSomethingWithPacket(wholePacket)
    

    【讨论】:

    • 请注意,f.read(1) 将阻塞,直到接收到字节或套接字的另一端关闭。这可能会给您带来麻烦,因为您将无法关闭客户端的套接字。查看this SO question 了解详细示例。哦,我多么希望这能奏效。
    猜你喜欢
    • 2019-06-06
    • 2011-11-01
    • 2012-12-21
    • 2015-02-02
    • 1970-01-01
    • 2013-11-25
    • 2012-12-02
    • 2020-05-18
    • 1970-01-01
    相关资源
    最近更新 更多