day34

新模块: 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: 表示错误信息的输出管道

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()

 

 
posted @ 2018-07-19 19:35  山东张铭恩  阅读(110)  评论(0编辑  收藏  举报