zoukankan      html  css  js  c++  java
  • 基于tcp的云盘上传下载的模拟

    老师的博客:

    server端

    import json
    import struct
    import json
    import struct
    import socket
    import os
    sk = socket.socket()
    sk.bind(('192.168.43.155',8080))
    sk.listen()
    
    conn,addr = sk.accept()
    dic_len = conn.recv(4)  # 4个字节 数字的大小
    dic_len = struct.unpack('i',dic_len)[0]
    content = conn.recv(dic_len).decode('utf-8')  # 70
    content_dic = json.loads(content)
    if content_dic['operate'] == 'upload':
        with open(content_dic['filename'],'wb') as f:
            while content_dic['filesize']:
                file = conn.recv(1024)
                f.write(file)
                content_dic['filesize'] -= len(file)
    elif content_dic['operate'] == 'download':
        file_path=content_dic['path']
        file_name=os.path.basename(file_path)
        file_size=os.path.getsize(file_path)
        dic_from={'file_size':file_size,'file_name':file_name}
        dic_from=json.dumps(dic_from).encode('utf-8')
        dic_lenth=struct.pack('i',len(dic_from))
        print(dic_lenth,type(dic_lenth))
        conn.send(dic_lenth + dic_from)
        with open(file_path,mode='rb') as f:
            while file_size>0:
                ret=f.read(1024)
                conn.send(ret)
                file_size -= 1024
        print('传输完成')
    else:
        print('错了')
    conn.close()
    sk.close()

    client端

    import os
    import json
    import struct
    import socket
    
    sk = socket.socket()
    sk.connect(('192.168.43.155',8080))
    
    def get_filename(file_path):
        filename = os.path.basename(file_path)#os.path.basename(path) 返回path最后的文件名。
        # 如果path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素
        return filename
    
    #选择 操作
    operate = ['upload','download']
    for num,opt in enumerate(operate,1):#枚举函数,第一个参数是对象,第二是是下标的开始计数
        print(num,opt)
    num = int(input('请输入您要做的操作序号 : '))
    if num == 1:
        '''上传操作'''
        file_path = input('请输入要上传的文件路径 : ')
        file_size = os.path.getsize(file_path)  # 获取文件大小
        file_name = get_filename(file_path)#获取文件路径
        dic = {'operate': 'upload', 'filename': file_name,'filesize':file_size}
        str_dic = json.dumps(dic).encode('utf-8')
        ret = struct.pack('i', len(str_dic))  # 将字典的大小转换成一个定长(4)的bytes
        sk.send(ret + str_dic)
        with open(file_path,'rb') as  f:
            while file_size:
                content = f.read(1024)
                sk.send(content)
                file_size -= len(content)
        print('上传成功')
    elif num == 2:
        '''下载操作'''
        download_path=input('请输入你要下载的路径')
        dic=json.dumps({'operate':'download','path':download_path}).encode('utf-8')
        download_path_unm=struct.pack('i',len(dic))
        sk.send(download_path_unm+dic)#发送信息
        get_information=sk.recv(4)#接受即将带来的信息的长度
        get_information_real=struct.unpack('i',get_information)[0]#转化为真是数字
    
        get_real_information=sk.recv(get_information_real).decode('utf-8')#接受,解压
    
        get_real_information=json.loads(get_real_information)
        download_file_name=get_real_information['file_name']
        download_file_size=get_real_information['file_size']
        with  open(download_file_name,mode='wb') as f:
                while download_file_size>0:
                    print(download_file_size)
                    code=sk.recv(1024)
                    f.write(code)
                    download_file_size -= 1024
    
        print('下载成功')
    sk.close()

    说明:

    上传老师写的,我自己是吧下载给补充的写了,所以上传和下载的代码应该还可以优化一下。

    下面是在写代码中遇到的问题,总结一下:

    1.struct中,把数字转化为4的固定长度的bytes类型,所以就不需要再进行encode操作,因为本身就是bytes类型的,而却其编码方式叫特别,只能通过unpack才能转化为数字,记住是int,通过其他方式。例如。gbk。utf-8decode是str类型,但是内容确实空白的·另外关于unpack得到的是个元祖,所以的到的值需要取第0位数,来取到你需要的数字。

    2,json模块,由于json是把数据类型给转化为str类型的,所以还需要在进行encode()的操作,来吧其转化为bytes类型的。所以拿到是,应该首先decode()。

    3,send的是时候可以采用(内容1+内容2)的形式,表示两次发送的

    4,下载上传是必需要把文件的大小拿到,然后采用相等的大小传输,所以需要把文件大小先传输过去,然后在进行同时的收发操作。

    5.while循环是,条件应该写成长度<0是结束,因为有很大的情况下,大小-=1024是不可能刚好减到0的,如果为负数的时候,条件还是为真,所以不会终止循环,然后就出不来了。

    6,数据传输和接受的时候都是以bytes的方式打开或者写入的,而且在不需要写编码方式,因为传输的有可能是视频。

  • 相关阅读:
    Windows系统之间文件互传
    PHP MySQL -2021.01.30
    Python MySQL
    [转载]python之函数的使用及异常处理2021.1.30
    python之文件操作
    Python学习-2021.1.28
    [转载]Metasploit漏洞攻击
    [转载]使用命令给windows用户提权
    [转载]nmap的使用
    Windows和Linux简单命令的总结
  • 原文地址:https://www.cnblogs.com/accolade/p/10537271.html
Copyright © 2011-2022 走看看