• 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()
     
  • 相关阅读:
    【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】
    【POJ】1835:宇航员【模拟】【三维行走】
    【BZOJ】3195: [Jxoi2012]奇怪的道路【状压/奇偶性】【思路】
    【10.24校内测试】【欧拉路径(有向+无向)】【双向链表/树状数组/线段树】
    【POJ】1840:Eqs【哈希表】
    【洛谷】4317:花神的数论题【数位DP】
    【POJ】1486:Sorting Slides【二分图关键边判定】
    算法模板
    Redis源码阅读一:简单动态字符串SDS
    总结下c/c++的一些调试经验
  • 原文地址:https://www.cnblogs.com/daien522556/p/9337917.html
Copyright © 2020-2023  润新知