处理黏包问题

struct 模块

# ### struct 模块使用
import struct
"""
pack     打包 
    把任意长度数字转换成具有固定4个字节长度的字节流
unpack   解包
    把4个字节长度的值恢复成原来的数字,返回元组
    
"""

# pack
# i => int  要转换的当前类型是整型
"""范围: -21亿~21亿左右 控制在1.8G之内"""
res = struct.pack("i" , 999999998)
print(res , len(res))

res = struct.pack("i" , 1111111119)
print(res , len(res))

res = struct.pack("i" , 3)
print(res , len(res))


res = struct.pack("i" , 2000000000)
print(res , len(res))

# unpack
# i => 把对应的数据转化成整型
tup = struct.unpack("i" , res)
print(tup) #(2000000000,)
print(tup[0])
 
 
"""
#解决黏包场景:
    应用场景在实时通讯时,需要阅读此次发的消息是什么
#不需要解决黏包场景:
    下载或者上传文件的时候,最后要把包都结合在一起,黏包无所谓.
"""

server 服务端

import socket
import time
import struct

"""
黏包现象:
    (1)发送端,数据小,时间间隔短,造成黏包
    (2)接收端,没有及时接受数据,可能把多次发送的数据当成一条截取.
"""

sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind( ("127.0.0.1",9001) )
sk.listen()
conn,addr = sk.accept()

# 收发数据的逻辑
strvar = input("[服务端]请输入您要发送的数据")
msg = strvar.encode()
length = len(msg)
res = struct.pack("i",length)

# 第一次发送数据 (数据长度)
conn.send(res)

# 第二次发送数据 (真实数据)
conn.send(msg)

# 第三次发送数据 (真实数据)
conn.send(b"world,hello")


conn.close()
sk.close()

client 客户端

import socket
import time 
import struct

sk = socket.socket()
sk.connect( ("127.0.0.1",9001)  )

time.sleep(2)
# 收发数据的逻辑


# 第一次接受数据 (数据长度)
num = sk.recv(4)
tup = struct.unpack("i",num)
print(tup[0])

# 第二次接受数据 (真实数据)
res = sk.recv(tup[0])
print(res.decode())

# 第三次接受数据 (真实数据)
res = sk.recv(1024)
print(res.decode())

sk.close()

 

posted @ 2020-11-14 15:13  流连、陌往返  阅读(27)  评论(0)    收藏  举报
点我跳转百度