最近工作遇到一个应用,用python实现一个server接收client发送过来的JSON格式的数据包,但是数据包会不预期的被截断分成多包或者多包被合并为一包数据,这样在收到的每一包数据的时候就会出现不能直接使用JSON API去解析的情况。
发送端:每次发送一个如下的字符串,
{"cmd":"message","display_time":0,"id":1,"timestamp":1543907634598,"info":null}
{"cmd":"status","display_time":0,"id":2,"auto":[{"status":0,"control_status":1,"speed_info":0,"status":0,"event":1}],"timestamp":1543907634598}
{"cmd":"message","display_time":0,"id":1,"timestamp":15439076528,"info":null}
接收端:并不是以3包(次)接收数据的,而后面JSON处理的时候必须是三包数据处理,所以需要特殊处理,好在发送的结尾会增加'\n'字符,所以我们接收的时候每次去check收到的字符串中是否有'\n'。
具体代码如下:
#!/usr/bin/python
#-*-coding:utf-8-*
from socket import *
import threading
import json
address='0.0.0.0' #监听哪些网络 127.0.0.1是监听本机 0.0.0.0是监听整个网络
port=8088 #监听自己的哪个端口
buffsize=8196 #接收从客户端发来的数据的缓存区大小
s = socket(AF_INET, SOCK_STREAM)
s.bind((address,port))
s.listen(5) #最大连接数
End="\n"
total_data='';data=''
def tcplink(sock,addr):
while True:
global total_data
recvdata=clientsock.recv(8192) #接收数据
if recvdata=='exit' or not recvdata:
break
total_data += recvdata
if total_data.find(End) != -1: #检查字符串中是否有'\n',有去处理
splitdata = total_data.split(End)
else:
continue #没有'\n',继续下一次接收
last_pair=total_data[-2]+total_data[-1]
num = 0
while num < len(splitdata) - 1:
jsdata = json.loads(splitdata[num])
print json.dumps(jsdata, sort_keys=True, indent=4, separators=(',', ':'))+","
num = num + 1
if End in last_pair:
total_data = ''
else:
total_data = splitdata[len(splitdata)-1]
clientsock.close()
if __name__ == "__main__":
while True:
clientsock,clientaddress=s.accept()
print('connect from:',clientaddress)
#传输数据都利用clientsock,和s无关
t=threading.Thread(target=tcplink,args=(clientsock,clientaddress)) #t为新创建的线程
t.start()
s.close()