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时不断累加总数据和收到的数据长度