zoukankan      html  css  js  c++  java
  • PYTHON-TCP 粘包

    1.TCP的模板代码
    收发消息的循环 通讯循环
    不断的连接客户端循环 连接循环
    判断 用于判断客户端异常退出(抛异常)或close(死循环)

    半连接池backlog listen(5)
    占用的是内存空间 listen监听请求限制的是请求数 不是链接数
    什么情况下会进入半连接池:来不及处理accept 或者客户端单方面终止连接
    半连接池的工作原理
    目前我们的程序是单线程 服务器要么处理通讯要么处理连接请求 无法同时进行
    1 必须绑定规定的ip和port
    2 必须对外稳定提供服务
    3 必须能支持并发

    服务端需要遵循的原则:
    1. 服务端与客户端都需要有唯一的地址,但是服务端的地址必须固定/绑定
    2. 对外一直提供服务,稳定运行
    3. 服务端应该支持并发

    2.远程CMD
    粘包问题
    一方发送空数据 导致程序卡死 今后会通过多线程处理


    3.粘包问题 TCP:流式协议
    引起粘包的TCP特点:
    1 数据流没有开头也没有结果,像水流一样
    2 TCP协议有一个nagle算法,

    解决粘包的方案 自定义报头

    1.先用报头传输数据的长度
    对于我们远程CMD程序来说 只要先传输长度就能解决粘包的问题
    但是如果做得是一个文件上传下载 除了数据的长度 还需要传输文件的名字 md5等等信息
    又该如何?
    解决方法:
    发送方
    1.先告诉对方你要发的数据的长度
    2.在发送真实数据
    接收方
    1.先接收数据的长度信息
    2.根据长度信息循环获取直到以获取的长度等于总长度

    2.自定义复杂报头 完成发送一些额外的信息 例如文件名
    1.将要发送的额外数据打包成一个字典作为报头
    3.先发送报头的bytes长度(转json字符串 转bytes字节)
    4.再发送报头数据
    5.最后发送真实数据

    #服务端: #客户端:
    # 执行命令
    # 显示错误信息和正确信息
    # 制作一个报头信息 (转json字符串 转bytes字节)
    # 发送报头长度 # 先接收报头的长度(int)
    # 发送报头 # 接收报头(字节)
    # 发送真实数据 # 解析报头 转为json字符串str,再转为字典dic
    # 根据报头内的信息,收取真实的数据



    涉及模块:
    struct
    整型转字节,转成的bytes是固定长度的
    i 表示int 长度为4字节 q表示long int 长度为8字节
    print(len(struct.pack("i",10240)))
    字节转整型 得到一个元祖!!!
    print(struct.unpack("q",struct.pack("q",10240))[0])
    struct.pack('i',整形变量)
    struct.unpack('i',字节变量)

    服务器端示例:
    # 为了方便存取 可以把需要的信息打包为一个字典
    dic{
    "filename":"仓老师视频教学 如何做炸鸡!",
    "md5":"xzxbzxkbsa1212121",
    "total_size":2121221
    }
    # 字典转字符串? json
    head_dic = str(dict)
    bytes = head_dic.encode("utf-8")
    # 先发送这个字典字符串的长度
    dic_len = len(head_dic)
    #将长度转为了 字节
    bytes_len = struct.pack("i",dic_len)
    # 发送报头的长度
    c.send(bytes_len)

    # 发送真实数据
    c.send(xxx.mp4.bytes)
    TCP能传的只有字节


    # 服务端
    #执行结果长
    p_len=len(stdout)+len(stderr)
    # 将报头信息dic转json字符串,编码为字节,字节的长度,用struct固定,发送报头长度
    # 发送报头(编码为字节)
    # 再发送真实数据stdout ,stderr

    # 客户端

    # 先接收报头长度 用struct unpack拿到元祖取[0]
    # 接收报头
    # 解析报头,解码,json反序列化拿到字典,通过字典获取字典中的总长度
    # 根据报头信息,收取真实的数据 按1024接受,判断当总长度>0时不断累加总数据和收到的数据长度





  • 相关阅读:
    使用闭包的注意点
    JS中的回收机制
    jQuery选择器之样式
    PNRPC 2017-2018 Gym101615I
    Verilog碎碎念
    Codeforces 420D. Cup Trick
    AGC017C. Snuke and Spells
    XVII Open Cup named after E.V. Pankratiev. GP of Tatarstan B. White Triangle
    SPOJ TETRIS2D
    AGC017B. Moderate Differences
  • 原文地址:https://www.cnblogs.com/du-jun/p/9911400.html
Copyright © 2011-2022 走看看