pythonsocket发送⼆进制数据的格式_pythonsocket⼆进制问题
在⼯作中经常会⽤到socket传输数据,例如客户端给服务器发送数据(双⽅约定了数据格式),在交测之前,⾃⼰⽤python写个接受数据的rver,解析下拼成的数据格式是否正确。⽤python写⽐C语⾔简单很多。
PS:实际上我是不会python的,⼯作中是C/C++开发,使⽤python纯属是为了偷懒^_^
举个具体的例⼦:通信双⽅约定的数据格式为
数据格式为⼆进制的,python需要⽤到struct模块处理⼆进制数据。struct模块中最重要的三个函数pack(), unpack(), calcsize()。因为struct相当于C语⾔中的结构体,unpack()返回的是⼀个元组。struct⽀持的格式如下表
注1)q和Q只有在机器⽀持64位时有意义;
注2)每个格式前可以有⼀个数字,表⽰个数;玲珑山
注3)s格式表⽰⼀定长度的字符串,4s表⽰长度为4的字符串,p表⽰的是pascal字符串;
注4)P⽤来转换⼀个指针,其长度和机器字长有关;
默认情况下struct根据本地机器字节顺序转换,也可以⽤格式中的第⼀个字符来改变对齐⽅式。定义如下:
注:⽆论数据包是python程序struct.pack()得到的,或者是C,C++,Java程序拼成的,只需保证client端和rver端字节顺序保持⼀致即可。浮士德简介
以⽂章开头的例⼦来说明pack()和unpack()函数:
注:测试环境中中⽂为utf-8编码(python的编码折腾了半天,也没太懂,这⾥不是重点)
仇池山1)pack(format, v1, v2, ...)按照指定的格式(format),把数据封装成字符串,例如
>>s=struct.pack("2i13si6s2i", 33, 13, "", 6, "冬季", 0, 0)
2)unpack(format, string) 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple,例如
>>us=struct.unpack("2i13si6s2i", s)
输出结果:高铁价格查询
>>print us
电气二龙四虎
(33, 13, '', 6, '\xe5\x86\xac\xe5\xad\xa3', 0, 0)
注: 中⽂部分是⼆进制,从元组中取出来再打印
>> print us[4]
冬季
找不到硬盘
注:对python下的中⽂编码感兴趣的同学可以研究下python环境编码(再次说明我真的不会python! >_
举个简单的例⼦:
#!/usr/bin/python
import socket
importstructimport os
import timeif __name__ == "__main__":
rver=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
rver.bind(("127.0.0.1", 51001)) #本机端⼝号51001
rver.listen(1)while (1):
镜子迷宫
conn,client=rver.accept()
msg= v(4) #total data lengthif len(msg) <= 0: #接收空数据包continuedata= struct.unpack("i", msg)
print"Recv Total length:%d"%(data[0])秦梦遥
process_len= 0msg= v(data[0])for i in range(0,4): #循环四次,分别取 url title content author
para= msg[process_len:(process_len + 4)]if len(para) < 4: #如果某⼀字段为空,不处理continuedata= struct.unpack("i", para) str_len= data[0]
print"%d"%(str_len)
para= msg[(process_len + 4):(process_len + 4 +str_len)]if len(para)
print"%s"%(data[0])
process_len= process_len + 4 +str_len
conn.clo()