新模块: subprocess
执行系统命令
r = subprocess.Popen('ls',shell=True,stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
subprocess.Popen(a,b,c,d)
a: 要执行的系统命令(str)
b: shell = True 表示确定我当前执行的命令为系统命令
c: 表示正确信息的输出管道
d: 表示错误信息的输出管道
执行系统命令
r = subprocess.Popen('ls',shell=True,stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
subprocess.Popen(a,b,c,d)
a: 要执行的系统命令(str)
b: shell = True 表示确定我当前执行的命令为系统命令
c: 表示正确信息的输出管道
d: 表示错误信息的输出管道
tcp协议:面向数据流形式的特点
tcp协议会发生粘包,因为两个机制,一个拆包机制,一个合包机制(nagle算法)
udp协议不会发生粘包,因为udp协议是面向数据包形式的通信
import socket import subprocess sk = socket.socket() sk.bind(('127.0.0.1',9090)) sk.listen() conn,addr = sk.accept() while 1: cmd = conn.recv(1024).decode('utf-8') res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE) std_out = res.stdout.read()# 读取正确的返回信息 std_err = res.stderr.read()# 读取错误的返回信息 if std_out: conn.send(std_out) else: conn.send(std_err) conn.close() sk.close() 服务器
import socket sk = socket.socket() sk.connect_ex(('127.0.0.1',9090)) while 1: cmd = input('请输入一个命令>>>') sk.send(cmd.encode('utf-8')) print(sk.recv(204800000).decode('gbk')) sk.close() 客户端
struct模块:
有一个方法,可以将一个21.3E以内的数字,转变成一个固定长度的bytes数据,长度为4b
res = struct.pack('i',num)
'i' : 表示的是int类型的数据
num : 表示要转换的数据
re = struct.unpack('i',res)将bytes数据转变回原数据
re是一个元组,原数据保存在元组的下标0的地方
import socket import os import json import struct sk = socket.socket() sk.connect(('127.0.0.1',9090)) l = ['upload','download'] for i,v in enumerate(l): print(i+1,v) dic = {'opt':None,'filename':None,'filesize':None} while 1: opt = input("请输入功能选项>>>")# 客户要执行的操作选项 if opt == '1': '''upload''' file_dir = input('请输入文件路径>>>')# 'E:/sylar/python_workspace/day34/作业/时间同步机制_client.py' file_name = os.path.basename(file_dir)# 获取文件名字 file_size = os.path.getsize(file_dir)# 获取文件大小 dic['opt'] = l[int(opt)-1] dic['filename'] = file_name dic['filesize'] = file_size dic_str = json.dumps(dic)# 将字典序列化成一个字符串形式的字典 dic_size = len(dic_str)# 获取字典的大小 ds = struct.pack('i',dic_size)# 把一个小于21.3E的一个数字转变成一个4字节长度的bytes sk.send(ds + dic_str.encode('utf-8'))# 发送给服务器 with open(file_dir,'rb') as f: while file_size: content = f.read(1024)# 文件内容 sk.send(content) file_size -= len(content) elif opt == '2': '''download''' pass else: print('有误') 客户端 sk.close()
import socket import json import struct sk = socket.socket() sk.bind(('127.0.0.1',9090)) sk.listen() conn,addr = sk.accept() dic_size = conn.recv(4)# 先接受4字节长度的一个bytes, 代表字典的大小 dic_size = struct.unpack('i',dic_size)[0]# 将这个特殊的bytes转变成原数字 dic_str = conn.recv(dic_size).decode('utf-8')# 根据字典大小去获取字典,以免和底下获取文件内容发生粘包 dic = json.loads(dic_str)# 反序列化 得到字典 opt filename filesize if dic['opt'] == 'upload': '''接收文件''' filename = '1'+dic['filename']# 将文件名字修改,防止重名 with open(filename,'wb') as f: while dic['filesize']: content = conn.recv(1024) f.write(content) dic['filesize'] -= len(content) elif dic['opt'] == 'download': '''给客户端传输文件''' 服务器 conn.close() sk.close()