乐趣区

关于网络编程:用-Python-写网络编程三

前言

明天是一个特地的节日,1946 年情人节(原文发表日期是 2021.2.14),世界上第一台计算机 ENIAC 在米国的宾夕法尼亚大学被 new 了,标记着新的时代到来。
计算机陪伴人类曾经走过了 75 个年头,所以明天,没啥特地的事件,请多去陪一陪本人家的电脑,手动狗头,手动狗头。
网络编程会是一个比拟宏大的常识体系,第三篇会开始讲如何 encode 和 decode。
第一篇的数据结构是提供给第三篇应用的,而后通过第二篇的通道进行传输。

复习功课
第一篇地址
第二篇地址

Tcp pickle

Tcp 网络流,加工过程也能够了解成是字节流到二进制流,字节就是第一篇提到的 bytes。
encode 压包就是把字节流转换到二进制流,那么 Python 是通过怎么做到的呢。

次要分为二种,pickle(python 独有序列化字节数组),struct(从 C 那边继承来的序列化字节数组的)库。
咱们看看 pickle 是如何序列化数据的。

def encode_pickle(packet:bytes):
    """
    压入 pickle
    :param packet: 
    :return: 
    """return pickle.pack(">i",len(packet))+packet

留神这里并没有发包进来,回顾后面的,须要先建设 socket 链接,确认地址,能力进行发包。
pickle.pack(fmt,*args) 的第一个参数 fmt 是个很重要的知识点。

先来理解下最重要的概念之一 fmt, 家喻户晓,Python 是不须要先申明内存宽度,能力编程的。
内存宽度是指内存外面占位的长度,在申明对象前会标注数据类型(动静语言没这个,动态语言很多有主动推断申明的 比方 golang var 和:=)

网络编程须要学习这块,是因为操作二进制, 粗疏的话会标记为有符号和无符号。有符号和无符号做一些原子计算,做减法的时候,局部语言须要做一些非凡解决,还好 Python 不必放心这些,有符号个别是指蕴含正数。
short 是有符号的 2 个字节的,unsigned short 是无符号的 2 个字节,正数这个下面图须要背下来。

网络自定义字节和字节序

下面代码外面是 int 和 unsigned int,fmt 后面是主机字节序,”>i” 代表大端有符号的 4 个字节,”<“ 代表小端,”!” 代表不必匹配。
临时不思考具体学字节序转换的问题,目前网络编程是模仿客户端往服务器发。
字节序别离有大端(big endian)和小端(little endian),程序的内容都是以字节为单位的,一个字节 8 位,每个地址对应一个字节。
大端模式就是将数据的高位放在低位地址,低位地址就是左侧。转 16 进制只是给人读的,int 类型 4 个字节,ff 6c 5a 4s。
小端就是大端反过来,是 4s 5a 6c ff。从这里能够发现大小端只是对内存寻址的程序无关,然而内存地址外面的 6c,5a 是不会变成 c6 和 a5 的
这块问题,后期不相熟的话,能够通过问需要来确认如何写。

数据类型前面数字除以 8 就是字节数,数字是 bit。
拿 JS 举个例子:buffer 做视图解决的,比方 Uint32Array,U 代表无符号,。int32 是 4 个字节,Array 能够了解为数组。
字节数组就是多个字节,Python 数据结构就是 bytes 或者 bytearray(这个和前者差异是内存不可变)

Uint64Array 那就是 8 个字节?这个是不非法的。这里有个定长和变长的概念,int 属于定长,int 是不能超过宽度 4 个字节的,所以不会有 Uint64Array,然而能够有 Uint16Array,16/8=2,在内存外面占位 2 个字节。

定长在具体实例内论述,不定长是比拟外围的局部,看下上面 2 个问题:
问题 1:援用类型,比方指针指向一个对象,如果操作这个对象,这个对象宽度是不会扭转的。
问题 2:long 类型,网络编程也是为了模仿客户端向服务器进行发包,long 类型也是不定长的,比方不是 8 的倍数,是 9 个字节。
看 9 个字节是怎么写的。

def encode_pack(packet:str or bytes,size:int,endian:str="big"):
    """
    压包 
    :param packet:
    :param size: 定长
    :param endian:
    :return:
    """
    return int(packet).to_bytes(length=size, byteorder=endian)

print(encode_pack("1256478912".encode("utf-8"),9))

当然这个模式并不是举荐的,更适合用 fmt 外面去拼接,比方大端 9 个字节 - -,间接用 >9s 就行了。
struct 和 pickle 实质是一样的,实质一样就好比 Json 和 bjson 和其余 json 一样,办法都是一样的。当初能够把后面的给串起来。

def encode_9_buffer(packet: bytes):
    """
    压入 9 个字节的缓存区
    :param packet:
    :return:
    """return struct.pack(">9s", len(packet).to_bytes(length=9, byteorder="big")) + packet

pg = "hello world".encode()
print(struct.calcsize(">9s"))  #长度 9
print(encode_9_buffer(pg)) #b'\x00\x00\x00\x00\x00\x00\x00\x00\x0bhello world'

pickle 和 struct 混合

后面 9s 是一整个包的例子,这里预报下,前面不定长,也是游戏产业最罕用的,第 4 篇会提到。以后章节其实能够满足互联网的一些 TCP 前置的网络编程了。
应用 pickle 压入缓存区 4 个字节大端 hello world,而后应用 struct 去解包还原,来验证正反序列化可兼容。
所以 python 写的后端如果是用 pickle 的,用 struct 也是能够的。

def encode_pickle(packet: bytes):
    """
    压入 pickle
    :param packet:
    :return:
    """return pickle.pack(">i", len(packet)) + packet

def decode_unpack(packet: bytes):
    """
    unpack 包 这里不蕴含 struct.unpack
    :param packet: 
    :return: 
    """
    # 因为包头是 4 个字节,合法性验证是先切出 4 个字节。if len(packet) >= 4:
        return packet[4:].decode()

if __name__ == '__main__':
    pg = "hello world".encode()
    packet = encode_pickle(pg)
    print(decode_unpack(packet))

回顾之前说的知识点。一个数据包由包头和包体组成,包头是 4 个字节(外面寄存着包体长度)。
简略判断合法性就是先看是否包残缺,包残缺由 2 个局部组成,第一个局部是 4 个字节,那么就是先判断大于等于 4 个字节,而后解包先去掉头部 4 个字节,那外面的就是包体内容。
包体内容还原就是 decode(), 上面看看如何取出包头外面的包体长度

struct.unpack(">i",packet[:4])

其余内容能够看第四篇文章。

本文在 2021.02.14 首发于 TesterHome 社区,作者是资深游戏测试开发工程师陈子昂。用 Python 写网络编程共四篇,明天给大家分享其中第三篇。原文链接:https://testerhome.com/topics/27910*

以上是明天的分享,你学废了吗~

想学习更多干货常识和前沿技术?

想结识测试行业大咖和业界精英?

欢送关注 2022 MTSC 大会(第十届中国互联网测试开发大会)

业界对 MTSC 大会的评估:落地、求实、有深度、重分享

中国互联网测试开发大会(Testing Summit China),由国内最大的测试开发技术社区之一 TesterHome 发动。始于 2015 年,已胜利举办了九届。从最后的 300 多人到 2019 年的近 2000 人后,始终放弃千人大会的规模。

为了保障议题品质,TesterHome 每年都会提前半年进行议题征集,再通过历时数月的审核,最终确定在大会分享的议题。MTSC 2022 的议题还在征集中,诚邀各位资深测试技术专家、品质治理经理和测试新秀们自荐 / 举荐议题!

提交议题形式

间接点击 https://www.wjx.top/vj/wZwCju3.aspx 进入投递入口,依照格局进行填写并提交即可,欢送自荐 / 举荐议题。

议题截止工夫

为便于评审组有更充沛工夫进行评审及与讲师进行沟通优化,为宽广参会者出现更好的议题,议题投稿(可无 ppt,有纲要等议题信息介绍即可)投递截止工夫提前为:2022 年 3 月 30 日

议题征集评比流程

总体流程:案例提交  > 初审核定 > PPT 提交 > 确认议题 > 会议演讲

总体工夫节点:
案例提交 >> 3 月 30 日
初审核定 >> 4 月 15 日
ppt 提交 >> 5 月 15 日
议题确认 >> 5 月 30 日
会议演讲 >> 7 月 22~23 日

讲师福利

  1. 锤炼演讲能力,加强集体品牌
  2. 取得和业内专家面对面交换的机会,博采众长
  3. 晋升公司品牌,给本人的团队减少吸引力
  4. 获取收费的大会门票和材料:
    每位讲师都会获赠 1 张大会门票,大会后续的 PPT 和视频都会第一工夫给到讲师
  5. 当地讲师由 MTSC 大会组委会承当差旅费用

MTSC 2022 早鸟票已轻轻开售,点击理解详情。

退出移动版