python学习第三十天:粘包问题

粘包

1.什么是粘包:

         粘包就是接收方不知道消息的界限,从而使发过来的多个消息/数据粘连在一起的现象

2.为什么会造成粘包:

         粘包的情况有两种:

         ①发送端由于nagle优化算法的原因,会将数据时间间隔很短、数据很小的消息/数据汇合到一起以后再进行发送,产生粘包;

         ②接受方不及时接收缓冲区的包,造成多个包接收(发送方发送了一段数据,但接收方只收了一小部分,下次发送方再次发送时,接收方会优先拿到上次没有接收完的数据,造成粘包)

3.怎么解决粘包问题

事例:

服务端:

import socket
import json
import struct
import subprocess

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8083))
server.listen(5)

while True:
    conn, client_addr = server.accept()
    while True:
        try:
            cmd = conn.recv(1024)
            if len(cmd) == 0: break
            obj = subprocess.Popen(
                cmd.decode('utf-8'),
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            stdout = obj.stdout.read()
            stderr = obj.stderr.read()
            header_dic = {
                'file_name': '返回文本',
                'file_size': len(stderr) + len(stdout),
                'md5': 'asgddasgdadag'
            }
            header_str = json.dumps(header_dic)
            header_bytes = header_str.encode('utf-8')
            conn.send(struct.pack('i', len(header_bytes)))
            conn.send(header_bytes)
            conn.send(stdout)
            conn.send(stderr)
        except Exception:
            break
    conn.close()

客户端:

扫描二维码关注公众号,回复: 1997702 查看本文章
import socket
import json
import struct


client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8083))
while True:
    cmd = input('>>:').strip()
    if len(cmd) == 0:continue
    client.send(cmd.encode('utf-8'))
    header_size = client.recv(4)
    header_bytes = client.recv(struct.unpack('i',header_size)[0])
    header_str = header_bytes.decode('utf-8')
    header_dic = json.loads(header_str)
    file_size = header_dic['file_size']
    recv_size = 0
    res = b''
    while recv_size < file_size:
        data = client.recv(1024)
        recv_size += len(data)
        res += data
    print(res.decode('gbk'))

猜你喜欢

转载自www.cnblogs.com/luck-L/p/9284656.html
今日推荐