python-实现tcp上传下载文件

Posted Gendan

tags:

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

import socket
import struct
import json
import os
sc= socket.socket()
sc.connect((\'127.0.0.1\',9997))
\'\'\' 验证用户名密码的函数,验证区 \'\'\'
def send_user(user,pwd):#发送用户的账户和密码

user_len = len(user.encode(\'utf-8\'))
leng = struct.pack(\'i\',user_len)
sc.send(leng)#用户的字节码长度
sc.send(user.encode(\'utf-8\'))#发送用户名的字节码

pwd_len = len(pwd.encode(\'utf-8\'))
leng = struct.pack(\'i\', pwd_len)
sc.send(leng)#密码的字节码长度
sc.send(pwd.encode(\'utf-8\'))#密码的字节码

\'\'\' 接收服务端的功能的函数,功能区 \'\'\'

上传文件的路径

上传文件的路径

path = r\'F:\\installsotf\\python file\\python全栈\\day30\\作业\\test_up\'

下载文件的保存位置

load_path=r\'F:\\installsotf\\python file\\python全栈\\day30\\作业\\download_file\'

接收服务端提供的功能列表,功能循环中第一个调用

def recv_function_list(sc):

leng = sc.recv(4)
leng = struct.unpack(\'i\', leng)[0]
cont = sc.recv(leng).decode(\'utf-8\')
return cont

将要发送的文件名和大小写到字典中,下面三个函数,实现文件的上传

def get_file(path):

file=os.path.basename(path)
size=os.path.getsize(path)
dic = {\'file\':file,\'size\':size}
return dic

def up_file(path,size):

with open(path, \'rb\')as fp:
    while size > 0:
        msg = fp.read(1024)
        sc.send(msg)
        size -= len(msg)

def upto_file(path):

# path=input(\'输入文件的绝对路径:\').strip()
if os.path.exists(path):
    dic = get_file(path)  # 获取字典【如果将path改成输入,就可以随意上传文件了】
    size = dic[\'size\']
    dic_byte = json.dumps(dic).encode(\'utf-8\')  # 先转成json,再转成bytes
    dic_leng = len(dic_byte)  # 获取bytes的长度
    leng = struct.[PayPal下载](https://www.gendan5.com/wallet/PayPal.html)pack(\'i\', dic_leng)
    sc.send(leng)  # 发送字典dic的长度
    sc.send(dic_byte)  # 发送字典的内容
    # 打开要操作的文件,用rb模式
    up_file(path, size)  # 调用上传文件
    return True
else:
    return False

下面这个函数实现文件的下载:

def down_file(path):#将文件下载到哪个位

# 收到用户的选择。
# print(58)
leng = sc.recv(4)  # 接收文件名和大小组成的字典
# print(60,len(leng))
leng = struct.unpack(\'i\', leng)[0]
dic = sc.recv(leng).decode(\'utf-8\')
dic = json.loads(dic)  # 获取到{‘file’:file,\'size\':size}
# print(dic)
# print(65)
path = os.path.join(path, dic[\'file\'])
size = dic[\'size\']
with open(path, \'wb\')as fp:
    while size > 0:
        cont = sc.recv(1024)
        fp.write(cont)
        size -= len(cont)

while 1:

print(\'1、登录\\n2、注册\')
chioce = input(\'输入的选择(q/Q退出):\').strip()
chioce_list=[\'登录\',\'注册\']
if chioce==\'1\' or chioce==\'2\':
    user = input(\'输入用户名:\').strip()
    pwd = input(\'输入密码:\').strip()
    sc.send(chioce.encode(\'utf-8\'))#发送选择给服务端
    send_user(user,pwd)
    ret = sc.recv(3).decode(\'utf-8\')#yes 或者 not
    if ret ==\'yes\':
        print(f\'{chioce_list[int(chioce)-1]}成功。\')
        \'\'\'  接收服务端提供功能的代码 :功能区\'\'\'
        if chioce==\'1\':#代表用户是在登录,且登录成功了,那么就可以享受服务端提供的上传下载文件功能。
            while 1:
                cont = recv_function_list(sc)
                print(cont)
                choice = input(\'输入你的选择(e/E退出):\').strip()
                if choice.isdecimal():
                    sc.send(choice.encode(\'utf-8\'))  # 告诉服务器要进行的操作
                    choice = int(choice)
                    if choice == 1:  # 上传文件
                        while 1:
                            path = input(\'输入文件绝对路径:\')
                            path = path.replace(\'\\\\\', \'/\')
                            ret = upto_file(path)
                            if ret:
                                print(\'上传成功\')
                            num = input(\'回车继续上传,stop退出上传:\').strip()
                            if num==\'goto\' or \'stop\':
                                sc.send(num.encode(\'utf-8\'))
                                if num == \'stop\':
                                    break
                            else:
                                sc.send(\'none\'.encode(\'utf-8\'))
                    elif choice == 2:
                        # 1、接收文件列表的长度和内容
                        len_list = sc.recv(4)  # 接收列表的长度字节码
                        leng = struct.unpack(\'i\', len_list)[0]  # unpacke成数字
                        leng = int(leng)
                        file_list = sc.recv(leng).decode(\'utf-8\')
                        file_list = json.loads(file_list)
                        while 1:
                            print(\'-*\' * 20)
                            print()
                            for i, name in enumerate(file_list, 1):
                                print(f\'{i},{name}\')
                            num = input(\'输入你选择:\').strip()
                            if num.isdecimal():
                                num = int(num)
                                if num > 0 and num <= len(file_list):
                                    # 2、发送文件序号的长度和内容
                                    leng = len(str(num).encode(\'utf-8\'))
                                    leng = struct.pack(\'i\', leng)
                                    sc.send(leng)  # 将文件序号的字节长度发送过去
                                    sc.send(str(num).encode(\'utf-8\'))  # 将文件序号发送过去。
                                    # print(\'调用down_file前\')#走到这里了
                                    # 3、接收文件的内容
                                    down_file(load_path)
                                    print(\'下载文件成功。\')
                                    # print(\'调用down_file后\')
                                    yes_not = input(\'回车继续下载,输入 stop 退出:\').strip()
                                    if yes_not==\'stop\' or yes_not==\'goto\':
                                        sc.send(yes_not.encode(\'utf-8\'))
                                        if yes_not == \'stop\':
                                            break
                                    else:
                                        sc.send("none".encode(\'utf-8\'))
                                else:
                                    print(\'无此选择。\')
                                    sc.send(\'0\'.encode(\'utf-8\'))
                            else:
                                print(\'输入有误。\')
                    else:
                        print(\'无此选择。\')
                elif choice.upper() == \'E\':
                    sc.send(\'E\'.encode(\'utf-8\'))
                    break
                else:
                    print(\'输入有误。\')
                \'\'\'接收服务端提供功能的代码的尾部:功能区\'\'\'
    else:
        print(f\'{chioce_list[int(chioce)-1]}失败。\')
elif chioce.upper()==\'Q\':
    #发送Q给服务端,说明要退出。
    sc.send(\'Q\'.encode(\'utf-8\'))
    print(\'退出系统。\')
    break
else:
    print(\'输入有误。\')

sc.close()

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

我在哪里更改此 Python 代码片段以将临时文件保存在 tmp 文件夹中?

TCP通信程序练习6——多线程实现文件上传

TCP通信程序练习6——多线程实现文件上传

Python 之 Socket编程(TCP/UDP)

java基础——TCP网络编程实现文件的上传

完全下载文件时,将下载的文件从一个片段传递到另一个片段