文件传输

Posted Mr。yang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件传输相关的知识,希望对你有一定的参考价值。

简单版

服务端

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# Author:Mr.yang
import socket
import struct
import os
import json
import subprocess

share_dir=rE:\Moudule_1\4.网络编程\5.文件传输\server\share

‘‘‘
相对于简单版的优化
1.报头信息少
2.struct的i格式有限制
‘‘‘
def run():
    phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.bind((127.0.0.1,8080))
    phone.listen(5)

    print(setting...)
    while True: # 链接循环
        conn,A = phone.accept()
        while True: # 通信循环
            try:
                #1.接收数据
                res = conn.recv(8096) #b‘get a.txt‘
                print(客户端数据:,res)

                #2.解析命令,提取相应命令参数
                cmds = res.decode(utf-8).split() #[‘get‘,‘a.txt‘]
                filename = cmds[1]

                #3.以读的方式打开文件,读取文件内容发送给客户端
                #第一步: 制定固定长度的报头
                header_dic={
                    filename: filename, #‘filename‘:‘a.txt‘
                    md5:xxdxxx,
                    file_size:os.path.getsize(r%s/%s%(share_dir,filename)) #os.path.getsize(‘E:\Moudule_1\4.网络编程\5.文件传输\server\share\a.txt‘)
                }

                header_json=json.dumps(header_dic)
                header_bytes = header_json.encode(utf-8)

                #第二步:先发报头的长度
                conn.send(struct.pack(i,len(header_bytes)))

                #第三步:再发报头
                conn.send(header_bytes)

                #第四步: 在发送真实的数据
                with open(%s/%s%(share_dir,filename),rb) as f:
                    # conn.send(f.read()) 文件非常大的话,全部读出来,就会非常占机器的内存
                    for line in f:
                        conn.send(line)

            except ConnectionResetError:
                break
        conn.close
    phone.close()

客户端

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# Author:Mr.yang
‘‘‘
recv不能设置数值特别大的原因:
1.在接收文件的时候可能超过指定数值
2.自己的操作系统的缓存不能无限大,最大也不能超过操作系统的缓存
‘‘‘
import socket
import struct
import json

download_dir = rE:\Moudule_1\4.网络编程\5.文件传输\client\download

phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect((127.0.0.1,8080))

while True:
    #1.发命令
    cmd = input(>>:).strip() #get a.txt
    if not cmd:continue
    phone.send(cmd.encode(utf-8))

    #2.以写的方式打开一个新文件,接收服务端发来的文件的内容,写入到客户的新文件中
    #第一步: 先收报头的长度
    obj = phone.recv(4)
    header_size = struct.unpack(i,obj)[0]

    #第二步: 再收报头
    header_bytes = phone.recv(header_size)

    #第三步: 从报头中解析出对真实数据的描述信息
    header_json = header_bytes.decode(utf-8)
    header_dic = json.loads(header_json)
    ‘‘‘
    header_dic={
                ‘filename‘: filename, #‘filename‘:‘a.txt‘
                ‘md5‘:‘xxdxxx‘,
                ‘file_size‘:os.path.getsize(filename)
            }
    ‘‘‘
    print(header_dic)
    total_size = header_dic[file_size]
    filename = header_dic[filename]

    #第四步: 接收真实的数据
    with open(%s/%s%(download_dir,filename),wb) as f: #用写的方式写,就会清空之前以读的模式的文件
        recv_size=0
        while recv_size < total_size:
            line = phone.recv(1024)
            f.write(line)
            recv_size += len(line)
            print(总大小:%s 已下载大小:%s%(total_size,recv_size ))

phone.close()

 

优化版

服务端

客户端

以上是关于文件传输的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从活动传输到片段? [复制]

如何解析 MPD 清单视频文件并获取图像适配集的片段?

流式传输短声音文件

VSCode自定义代码片段——.vue文件的模板

使用列表将值从一个类传输到另一个类

VSCode自定义代码片段2——.vue文件的模板