这篇文章主要介绍“python中怎么自定义pack和unpack”,在日常操作中,相信很多人在python中怎么自定义pack和unpack问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python中怎么自定义pack和unpack”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
因为TCP协议是流式协议所以数据包之间没有边界,有时会因为操作系统缓存机制、网络延迟等原因造成2次间隔时间较短、数据量较少的数据合并成一次发送。因此影响了数据的完整性。
常见的解决方式是通过自定义协议厘清数据包之间的边界。
发送方:
1.发送数据包前先计算长度,再将int型长度数据转换成4字节的bytes型;
2.先发送4字节bytes型长度数据,再发送数据包。
接收方:
1.先接收4字节bytes型长度数据,将其转换成int型长度数据。
2.只接收指定长度的数据。
以上协议是服务端和终端双方均要遵守的自定义协议。这样就可以解决粘包问题。
通常而言消息大小设为1024字节,发送消息前要先发送消息的长度,然后再发消息。接收时也是要先接收长度,再接收消息。
发送文件时要先计算文件的大小,然后发送文件的长度,再发送文件。接收时要先接收文件的大小,socket文件收发缓存大小通常设为65535。注意:文件发送时发送方发送的数据包大小是固定的,但接收方每次收到的数据包大小不固定,每次接收后要用文件长度减去接收到的数据包长度,判断剩余未接收文件长度小于1才算完成。
处理粘包问题我查阅了很多资料,看到绝大多数人都是import struct,使用struct.pack和unpack来完成int数据与bytes相互转换的工作。但是我觉得struct模块的pack和unpack有2个缺陷:一是表示数值范围是-2147483648至2147483647,负值在计算数据长度完全用不上,会造成上传、下载文件大小不能超过2个G,unpack返回的是一个元组,还要对元组解包才能使用。所以我尝试自己写了一个pack和unpack在下面分享给大家。
def pack(n):if n >= 4294967296 or n < 0:raise ValueError('The value is out of range.')values = ((0b11111111000000000000000000000000, 24), (0b111111110000000000000000, 16), (0b1111111100000000, 8), (0b11111111, 0))ret = b''for i in values:x = (n & i[0]) >> i[1]x = x.to_bytes(length=1, byteorder="big")ret += xreturn ret
def unpack(numlist):if len(numlist) != 4:raise ValueError("The bytes length must be 4.")values = (24, 16, 8, 0)ret = 0i = 0while i < 4:n = numlist[i]ret += n << values[i]i += 1return ret
代码说明:
自定义的pack函数表示范围是0-4294967295,上传、下载文件长度在4个g以内都不会报错。
在该函数中通过按位与配合位移算法以及python3内置函数to_bytes()来完成功能,不需要另外import。
自定义的unpack函数直接返回int型数值,不需要解包。在这个函数里全部是自定义的代码,没有引用任何函数也没有导包,通过位移运算完成bytes转换成int。
到此,关于“python中怎么自定义pack和unpack”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。