解决黏包的问题
#server import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() conn,addr = sk.accept() while True: cmd = input('>>>>>>') if cmd == 'q': conn.send(b'quit') break conn.send(cmd.encode('gbk')) num = conn.recv(1024).decode('utf-8') print(num) conn.send(b'ok') res = conn.recv(int(num)).decode('gbk') print(res) conn.close() #client import socket import subprocess sk = socket.socket() sk.connect(('127.0.0.1',8080)) while True: cmd = sk.recv(1024).decode('gbk') if cmd == 'q': break res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) std_out = res.stdout.read() std_err = res.stderr.read() sk.send(str(len(std_out)+len(std_err)).encode('utf-8')) sk.recv(1024) #ok sk.send(std_out) sk.send(std_err) sk.close()
struck模块
#server import socket import struct sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() conn,addr = sk.accept() while True: cmd = input('>>>>>>') if cmd == 'q': conn.send(b'quit') break conn.send(cmd.encode('gbk')) num = conn.recv(4) #4 num = struct.unpack('i',num)[0] #2048 res = conn.recv(int(num)).decode('gbk') #2048 print(res) conn.close() sk.close() #client import socket import struct import subprocess sk = socket.socket() sk.connect(('127.0.0.1',8080)) while True: cmd = sk.recv(1024).decode('gbk') if cmd == 'q': break res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) std_out = res.stdout.read() std_err = res.stderr.read() len_num = len(std_out)+len(std_err) num_bytes = struct.pack('i',len_num) sk.send(num_bytes) sk.send(std_out) sk.send(std_err) sk.close()
网络上传输的所有数据都叫数据包
数据包里的所有数据都叫报文
报文里里有ip地址 mac 端口号
所有报文都有报头
协议报头 接收多少个字节
定制报文 :复杂的应用上就会用到
传输文件的时候就够复杂了
文件名字
文件大小
文件类型
# head = {'filename':'test','filesize':409600,'filetype':'txt','fialpath':r'/user/bin'}
# 报头的长度 先接收4个字节
# send(head) #报头 #根据4个字节获取报头
# send(file) #报文 #从报头中获取filesize,然后根据filesize接收文件
如果跳出了我们所了解的端口ip协议
我们写的程序也需要多次发送数据或者发送多个数据
我们也可以自定制协议——本质上就是一种约定