day31
一.流式协议
tcp流式协议===>粘包问题(***)
只有tcp协议有粘包问题,udp协议没有
socket收发消息的原理:
解决方案:自定义应用层协议
注意:
head+data
head的长度必须固定
引子:
tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住
client.py
from socket import *
client = socket(AF_INET, SOCK_STREAM)
# print(client)
client.connect(('127.0.0.1', 8080))
while True:
cmd = input(">>: ").strip()
# 如果输入为空,就继续输入
if len(cmd) == 0:
continue
client.send(cmd.encode('utf-8'))
print('=======>')
data = client.recv(1024)
print('111111')
print(data.decode('utf-8'))
client.close()
sever.py
from socket import *
server = socket(AF_INET, SOCK_STREAM)
# print(server)
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
conn, client_addr = server.accept()
print(conn)
print(client_addr)
while True:
try:
data = conn.recv(1024)
conn.send(data.upper())
except Exception:
break
conn.close()
server.close()
两种情况下会发生粘包
发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据很小,
会合到一起,产生粘包)
接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只
收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)
远程执行命令程序解决粘包问题
为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据
struct模块
该模块可以把一个类型,如数字,转成固定长度的bytes