简单基于TCP的文件传输

该文章展示了如何使用Python进行文件传输,包括客户端和服务器端的脚本实现。通过套接字(socket)库,客户端发送文件名请求,服务器响应并发送文件内容。整个过程涉及TCP连接、JSON序列化和文件I/O操作。
摘要由CSDN通过智能技术生成

基于python的文件传输

生活中我们如何通过脚本进行传输文件呢,以下提供如何进行传输txt,jpg等格式的文件

代码如下:

客户端.py

import socket
import time
import threading
import struct   #将int类型打包成byte类型
import json  #反序列化
path=r''
def run():
    cmd=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建一个套接字对象,tcp格式,面向网络
    cmd.connect(('127.0.0.1',8081))   #连接测试地址,并且设置端口号
    while True:
        try:
            #1.发命令
            cmd1=input("请输入文件名称").strip()  #【get,a.txt】
            if not cmd1: continue    #如果没有命令直接继续执行
            cmd.send(cmd1.encode('utf-8'))     #将发送的命令通过操作系统并且通过utf-8编码
            #2.拿命令的结果,并且打印
            #第一步,先拿到数据的长度
            header=cmd.recv(4)    #接收一下报头的长度
            header_size=struct.unpack('i',header)[0]  #将报头的byte类型解压成int类型
            header_bytes=cmd.recv(header_size)  #接收数据部分
            header_json=header_bytes.decode('utf-8');  #将数据的byte类型经过解码utf-8
            header_dic=json.loads(header_json)  #通过json的包进行反序列化成字符串类型
            print(header_dic)   #打印一下字符串
            total_size=header_dic['file_size']  #取出字符串中总长度
            filename=header_dic["filename"]  #取出输入的姓名
            #第二步,从报头解析出,从filename的报头进行解析
            num=0
            with open('%s\%s'%(path,filename),'wb') as file:
                recv_size = 0   #设置接受的字符长度
                while recv_size < total_size:  #经过循环遍历出总长度
                    data = cmd.recv(1024)  #接收1024个字节的长度
                    file.write(data)   #写出文件数据
                    recv_size+=len(data)
                    num+=1
                    print("正在下载: {},总共大小 {},下载进度为{:.2%}".format(recv_size, total_size,(recv_size/total_size))+"{"+"|"*(num)+"}")
                print("it is be download successfully")
        except:
            print("指定文件不存在")
    cmd.close()

if __name__ == '__main__':
    print("i am parents process, my ID is"+threading.current_thread().name)
    print("waiting for  connecting")
    path=input(r'请输入要下载的路径')
    threading1=threading.Thread(target=run)
    threading1.start()
    print("i am child process, My ID is  "+threading1.name)
    time.sleep(10)

服务器端.py

import socket
import subprocess
import json
import os
import struct
import threading
path=r'D:\pythonProject\testfile\文件传输\share\share'   #注意修改服务器端的文件夹
def run():
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建套接字对象设置tcp格式并且事面向网络的类型
    phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    # print(phone)
    #2.绑定手机卡
    phone.bind(('127.0.0.1',8081))
    #3.开机
    phone.listen(5)
    #4.等电话连接
    print('starting....')
    while True:
        conn,client_addr=phone.accept() #等待客户端主机被接听的过程
        print(client_addr)
        #收发消息
        while True:#通讯循环
            try:
                #1.收命令
                res=conn.recv(8096)  #[get,filename]
                if not res: break
                cmd=res.decode('utf-8').split()
                filename=cmd[1]
                #2.执行命令
                # obj = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                # stdout=obj.stdout.read()
                # stderr=obj.stderr.read()
                #3.把命令的结果返回给客户端
                #第一步制作固定长度的报头
                header_dic={
                     'filename':filename,
                     'md5':'xxxdxx',
                     'file_size':os.path.getsize(r'%s\%s'%(path,filename)),
                }
                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'%(path,filename),'rb') as file:
                    for line in file:
                        conn.send(line)
            except:
                print("指定文件不存在")
                break
        #挂电话
        conn.close()

    phone.close()


if __name__ == '__main__':
    run()

结果截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值