[英]Decoding tcp packets using python
我正在嘗試解碼通過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,這種方法還可以。 任何建議將不勝感激。 提前致謝
謝謝
我將創建一個類,負責解碼來自流的數據包,如下所示:
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)
TCP在接口級別提供數據流,而不是單個數據包。 如果需要離散數據包,則可以使用UDP(並自行處理丟失或亂序的數據包),或將一些數據分隔符插入行內。 聽起來您已經用STX / ETX作為分隔符了。 但是,請注意,您從TCP堆棧的一個數據塊中獲得了多個消息。
請注意,除非進行其他處理,否則顯示的代碼中的data
不一定包含整數的消息。 也就是說,最后一個STX可能沒有匹配的ETX。 沒有STX的情況下,ETX將位於下一個data
塊中。
您可能應該從TCP數據流中讀取單個消息,並在出現消息時將其返回。
嘗試scapy ,一個功能強大的交互式數據包處理程序。
數據從哪里來? 與其嘗試手動解碼,不如使用出色的Impacket軟件包:
不錯,很簡單... :)
訣竅在文件對象中。
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.