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