반응형
출처 : http://stackoverflow.com/questions/2184181/decoding-tcp-packets-using-python
파이썬을 사용하여 TCP 패킷 decode하기
저는 TCP 접속을 통해 데이터를 decode하려고 합니다. 그 패킷은 작고 100바이트를 넘지 않습니다. 하지만 제가 받은 그 패킷들이 많을 때 그 패킷 중 일부는 결합 됩니다. 이를 방지할 수 있는 방법이 있습니까? 저는 파이썬을 사용합니다.
저는 그 패킷들을 분리하고 싶소 제 소스는 밑에 있습니다. 패킷은 STX 바이트로 시작하며 ETX 바이트로 끝납니다. STX 뒤의 바이트는 패킷 길이이며, (패킷 길이가 5 미만이면 유효하지 않습니다.) checksum은 ETX 이전 바이트입니다.
def decode(data):
while True:
start = data.find(STX)
if start == -1: #메세지에 STX가 없다면
pkt = ''
data = ''
break
#stx 발견 , 다음 바이트는 길이
pktlen = ord(data[1])
#ETX로 메세지가 끝나는 지 체크 또는 checksum이 유효하지 않을 때
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)
데이터 스트림에서 여러 개의 패킷이 있다면 리스트의 모음으로 패킷을 리턴하거나 첫 번째 패킷만 리턴하는 것이 최선입니다.
저는 C는 익숙하지만 파이썬에 익숙하지 않습니다. 이 방법이 괜찮나요? 어떠한 충고도 감사합니다.
5 개의 답변 중 1 개의 답변만 추려냄.
저는 이것처럼 스트림에서부터 패킷을 decoding에 대응하는 클래스를 만들었습니다.
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' 카테고리의 다른 글
파이썬 list comprehension에서 if/else 구문 사용법? (0) | 2017.08.10 |
---|---|
파이썬 - UTC 날짜시간 문자열을 local 날짜시간으로 변환하기 (0) | 2017.05.29 |
Python에서 상수를 만드는 방법 (0) | 2017.02.20 |
Python 3과 MySQL (0) | 2017.02.07 |
Linux TA-Lib 설치 외 (0) | 2016.11.04 |