前一阵在写一个自动测试程序时需要按照特定字符对收到的数据进行帧的分割,原有要求是有每帧前后各有一个同样的特殊字符,当时估计下时间还够,想将其扩展为一个较为通用功能,即每帧数据前有各有一个特殊字符表示开始和结束,但前后这两字符可以不同,也可以只有一个(在头在尾分割效果不同),同时学习了一阵python,感觉其处理这类问题还比较合适,完成了以下初步的代码,此段代码性能上还需优化:
def frame_read(fd,head,tail,timeout):
'return -- donot recv data return None,recv data but wrong format return [],else return data in tupe format, /
frame_len -- each frame cmd len,'
if fd is None or len <= 0:
print 'fd is None or len <= 0,'
return None
fd_type = check_obj_type(fd)
# print 'connect obj type is %s' % fd_type
if fd_type == 'invalid_type':
return None
cur_time = time.time()
data = ''
lines = []
received = False
head_found = False
head_len = len(head)
tail_len = len(tail)
temp = None
frame_len = 512
hex_str = ''
while 1:
if is_timeout(cur_time,timeout):
print 'wait data timeout.'
if not received:
return None
else:
if head == '' and tail == '':
lines.append(frame_pack(data))
elif tail == ''and data != '':
lines.append(frame_pack(head+data))
return lines
try:
if fd_type == 'socket':
hex_str = fd.recv(frame_len)
elif fd_type == 'serial':
hex_str = fd.read(frame_len)
else:
return None
except error,e:
pass
if len(hex_str):
hex_str = ' ' + asc2hexchar(hex_str,' ')
received = True
data += hex_str
# print 'recv new cmd : %s' % data
if head == '' and tail == '':
continue
while 1:
if not head_found:#start find head
if head == '':
head_found = True
continue
head_pos = data.find(head)
if head_pos == 0:
head_found = True
data = data[head_len:]
elif head_pos > 0:
head_found = True
if tail == '':
line,data = data[:head_pos],data[head_pos+head_len:]
temp = head + line
else:
line,data = data[:head_pos+head_len],data[head_pos+head_len:]
else:
break
else:#start find tail
if tail == '':
if temp:
lines.append(frame_pack(temp))
temp = None
head_found = False
continue
tail_pos = data.find(tail)
if tail_pos == 0:
if head != tail:
data = data[tail_len:]
head_found = False
elif tail_pos > 0:
line,data = data[:tail_pos+tail_len],data[tail_pos+tail_len:]
line = head +line
lines.append(frame_pack(line))
head_found = False
else:
break