第70天python学习TCP粘包解决方案struct模块
接下来我们先来介绍下可以解决黏包的模块的用法:
struct
python中的struct模块就提供了这样的机制,该模块的主要作用就是对python基本类型值与用python字符串格式表示的C struct类型间的转化(This module performs conversions between Python values and C structs represented as Python strings.)。stuct模块提供了很简单的几个函数,下面写例子。
两个函数:pack()、unpack()
struct模块最重要的两个函数就是pack()、unpack()方法
打包函数:pack(fmt, v1, v2, v3, ...)
解包函数:unpack(fmt, buffer)
服务器:
import struct
# pack 把任意长度的数字转化成固定4个字节长度的字节流
# unpack 将4个字节的值恢复成原本的数据,最后返回一个元组
res = struct.pack("i",2372722) #不能超过int 范围
print(res)
print(len(res))
res = struct.unpack("i",res)
print(res)
print(res[0],type(res[0]))
import struct
import socket
tcp_sever = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#在bind方法之前加上这句话,可以让一个端口重复使用
tcp_sever.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
#绑定地址端口(在网络上注册主机)
tcp_sever.bind(("127.0.0.1", 8080))
tcp_sever.listen(5)
conn,addr = tcp_sever.accept()
inp = input(">>>msg:")
msg = inp.encode("utf-8")
#发送数据的长度通过pack进行替换,变成具有固定长度的4个字节的值
res = struct.pack("i",len(msg))
conn.send(res)
#接下来,开始真正的发送数据
conn.send(msg)
conn.send("world".encode("utf-8"))
res = conn.recv(1024)
print(res)
print(res.decode("utf-8"))
#四次挥手
conn.close()
#退还端口
tcp_sever.close()
客户端:
import socket
import time
import struct
tcp_clint = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp_clint.connect(("127.0.0.1", 8080))
time.sleep(0.1)
#接收4个字节长度,它实际要发送的那个数字转化来的
n = tcp_clint.recv(4)
n = struct.unpack("i",n)[0]
print(n)
#接下来接收服务端发送过来的数据
res1 = tcp_clint.recv(n)
print(res1.decode("utf-8"))
res2 = tcp_clint.recv(1024)
print(res2.decode("utf-8"))
#空格不是ascii编码中,大家注意
tcp_clint.send(b'likejjjhkjhjhk')
#关闭连接
tcp_clint.close()
posted on 2019-11-19 21:45 坚持是多么伟大的事情 阅读(217) 评论(0) 编辑 收藏 举报