Day30 python基础--网络编程基础-粘包

一,粘包现象

  1.合包机制:

    数据长度很短,包与包之间的间隔短

  2.拆包机制:

    大数据会发生拆分

    不会一次性的全部发生到对方

    对方在接收的时候很可能没有办法一次性接收到所有的信息

    那么没有接收完的信息很可能和后面的信息粘在一起

  3.粘包现象只发生在tcp协议

    tcp协议的传输是流式传输

    每一条消息与信息之间是没有边界

  4.udp协议中不会发生粘包现象的

    适合短数据的发生

    不建议你发送过长的数据

    发生过长的数据会增大你数据丢失的几率

二,粘包现象总结:

  在程序中会出现粘包:

    收发数据的边界不清晰

    接收数据这一端不知道要接收数据的长度到底有多少

三,解决粘包现象的方法:

  解决方案1:

    自定义协议,根据接收的长度控制

    弊端:

      复杂

      最多只能一次传递9999个字节

#server端
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9090))
sk.listen()
conn,addr = sk.accept()
s = input('>>>')  # 'a'*20
str(len(s))  # '20'
str(len(s)).zfill(4)+str(len(s))

#client端
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9090))
ret1 = sk.recv(4)
num1 = int(ret1.decode('utf-8'))
ret = sk.recv(num1)
print(ret)
ret2 = sk.recv(4)
num2 = int(ret2.decode('utf-8'))
ret = sk.recv(num2)
print(ret)
sk.close()

  解决方案2:

    struct模块能够把不管多长的数据都转换成一个4位的字节

#server端
import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9090))
sk.listen()
conn,addr = sk.accept()
while True:
    s = input('>>>').encode('utf-8')
    pack_num = struct.pack('i',len(s))  #‘i’指定int数据类型
    conn.send(pack_num)
    conn.send(s)
conn.close()
sk.close()


#client端
import socket
import struct
sk = socket.socket()
sk.connect(('127.0.0.1',9090))
while True:
    pack_num = sk.recv(4)
    num = struct.unpack('i',pack_num)[0]
    ret = sk.recv(num)
    print(ret.decode('utf-8'))
sk.close()

四,自定义协议的作用

# 统计数据的长度
# 通过struct模块,处理这个长度
# 得到一个4个字节的结果
# 先发送4个字节的长度
# 再发送数据
#10240/20480
# 另一端先接收4个四个字节
# 通过strut来处理这四个字节,拿到数据的长度
# 安照数据的长度来接收
原文地址:https://www.cnblogs.com/lianyeah/p/9647620.html