⽤struct模块实现pythonsocket收发⾃定义TCP包
最近跳槽到西安⼀家机器⼈公司,我们的产品属于教育机器⼈的范畴,为了增强客户吸引⼒,引进了⼀个智能家居公司的产品API接⼝,让机器⼈来操作智能家居着装
该公司的智能家居API是⾃定义TCP包,即直接在TCP头后⾯写⾃定义数据结构:
客户端请求下载 家具数据库 的格式
命令字(4字节,⼩端)
0x4c
服务器返回请求结果 的格式
命令字(4字节,⼩端)payload长度(4字节,⼩端)payload(N*1字节)
0x4311262(尺⼨很⼤)sqlite数据库
默认python socket只能收发字符串,需要借助struct才能收发⼆进制数据
发送请求
cmd_word = 0x4c
tx_buf = struct.pack('<I', cmd_word)
sock.ndall(tx_buf)
tx_buf据struct的⽂档说是其对输⼊编码⽣成的字符串,⽤type(tx_buf)显⽰确实是<type 'str'>,print tx_buf显⽰字母L
但len(tx_buf) == 4, print repr(tx_buf)显⽰
'L\x00\x00\x00'
也就是说len('L\x00\x00\x00') == 4
奖学金主要事迹对于从C语⾔转过来的⼈来说,上⾯情况真是理解不能,但它就是发送成功了
蜜蜂的外形接收应答
fp = open('hou.db', 'wb+')
recv_cnt = 0
while True:
rx_buf = v(4096)
len_buf = len(rx_buf)
if len_buf ==0:
break
if recv_cnt == 0:
创新项目计划书cmd_word, data_len_total = struct.unpack(rx_buf[0:8])
buf = buffer(rx_buf, 8, len_buf - 8)
fp.write(buf)
俄罗斯旅游签证el:
buf = buffer(rx_buf)
零钱包
准时用英语怎么说fp.write(buf)
recv_cnt = recv_cnt +1
注意:
0、接收⾃定义帧头时⽤unpack,可以获得结构体各字段取值
1、接收⾃定义帧内容(字节流)时不⽤unpack,因为unpack返回的是tuple,⽽write不⽀持tuple类型
2、因为是⼆进制写⼊,所以必须将str转成buffer类型tobe18
3、⼆进制数据很⼤时,底层会拆分成多个以太⽹帧,如果你ndall后马上recv,则可能只收到1448字节,不要担⼼,这是因为你recv时内核协议栈只有⼀帧这么多数据,它全部返回给你了,满⾜socket编程的标准