• TCP协议--黏包现象



    # 黏包现象
    # 本质: tcp协议是流式传输,信息与信息之间没有边界
    # 为什么会造成黏包
    # 合包机制: 在发送端,由于两条消息发送的间隔很短,且这两条消息本身很短, 在发送时被合并成一条消息
    # 在接收端,由于接受不及时导致两条先后到达的信息在接收端黏在了一起
    # 解决黏包问题 -- 自定义协议>> struct模块: 把2**31(2GB)以内的数字变成固定的4个字节
    # 简单的形式
    # 先发送数据的长度,再发送数据
    # 相对规范并复杂的形式
    # 先把所有想发送的数据信息放到字典里,
    # 再发送字典的长度
    # 再发送字典
    # 最后发送内容
    import os
    import json
    import struct
    import socket
    
    sk = socket.socket()
    sk.connect(('127.0.0.1', 9001))
    
    filepath = input('请输入文件路径 :')
    filename = os.path.basename(filepath)              # os.path.basename 通过文件的路径,得到文件名
    filesize = os.path.getsize(filepath)               # 得到文件的大小
    dic = {'filename': filename, 'filesize': filesize} # 将文件名, 文件大小写进字典
    str_dic = json.dumps(dic)                          # 将字典序列化成字符串形式的字典
    bytes_dic = str_dic.encode('utf-8')                # 将字符串形式的字典 转成 字节
    len_dic = len(bytes_dic)                           # 得到 字节的长度
    bytes_len = struct.pack('i', len_dic)              # 用struck.pack() 将字节 转换成4位的字节
    sk.send(bytes_len)                                 # 发送得到的4位字节
    sk.send(bytes_dic)                                 # 发送字节
    with open(filepath, 'rb') as f:
        content = f.read()                             # 以rb模式 读取到文件中的内容
        sk.send(content)                               # 发送内容
    sk.close()
    
    # 先发送字典的长度
    # 再发字典 {'filename':xxxx,'filesize':xxxxx}
    # 再发文件内容
    解决黏包--client端
    
    
    import json
    import struct
    import socket
    
    sk = socket.socket()
    sk.bind(('127.0.0.1', 9001))
    sk.listen()
    
    conn, addr = sk.accept()
    num = conn.recv(4)                               # 接收4位字节
    num = struct.unpack('i', num)[0]                 # 读取4位字节, 获得字典长度
    str_dic = conn.recv(num).decode('utf-8')         # 读取字典长度, 得到字符串形式的字典
    dic = json.loads(str_dic)                        # 将字符串形式的字典反序列化, 得到字典
    with open(dic['filename'], 'wb') as f:
        content = conn.recv(dic['filesize'])         # 接收从客户端发来的, dic['filesize']这么大的文件内容
        f.write(content)
    
    conn.close()
    sk.close()
    解决黏包--server端
     
  • 相关阅读:
    Spark官方文档——本地编写并运行scala程序
    scala函数组合器
    scala数组
    scala实现kmeans算法
    Nginx 服务器安装及配置文件详解
    OpenVAS开源风险评估系统部署方案
    Elasticsearch和Head插件安装
    手把手教你在CentOS 7.4下搭建Zabbix监控(转)
    elasticsearch6.X 及head插件部署(完整版)
    Vim配置(python版)
  • 原文地址:https://www.cnblogs.com/LL97155472/p/10682895.html
Copyright © 2020-2023  润新知