1

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

我试图分离数据包,我的来源如下。数据包以 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,这种方法可以吗。任何建议将不胜感激。提前致谢

谢谢

4

5 回答 5

5

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

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)
于 2010-02-02T15:51:33.517 回答
4

TCP provides a data stream, not individual packets, at the interface level. If you want discrete packets, you can use UDP (and handle lost or out of order packets on your own), or put some data separator inline. It sounds like you are doing that already, with STX/ETX as your separators. However, as you note, you get multiple messages in one data chunk from your TCP stack.

Note that unless you are doing some other processing, data in the code you show does not necessarily contain an integral number of messages. That is, it is likely that the last STX will not have a matching ETX. The ETX will be in the next data chunk without an STX.

You should probably read individual messages from the TCP data stream and return them as they occur.

于 2010-02-02T13:33:40.307 回答
3

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

于 2010-02-02T14:02:00.903 回答
0

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

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

于 2010-02-02T13:53:34.167 回答
0

很好很简单...... :) 诀窍在于文件对象。

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)
于 2010-04-10T22:10:01.593 回答