Python编程:socket实现文件传输(文件服务器简易版)

题目:

  使用 socket 编程实现一个简单的文件服务器。客户端程序实现 put 功能 ( 将一个 文件从本地传到文件服务器 ) 和 get 功能 ( 从文件服务器取一远程文件存为本地 文件 ) 。客户端和文件服务器不在同一台机器上。
  客户下载文件:get 文件名 如:get file1.txt
  客户上传文件:put 文件名 如:put file2.txt

  注:下面代码是在一台机器上实现的,如果要在不同机器上,将客户端连接服务器那里的IP地址改为服务器的IP地址即可(前提要求:服务器和客户端能ping通)。

服务器端代码

# encoding=utf-8
# 服务器端
import socket
import os

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 9000))  # 绑定监听端口
server.listen(5)  # 监听
dirPath = 'F:\\fileServer\\';  # 文件服务器位置

print("服务器运行中···")

while True:
    conn, addr = server.accept()  # 等待连接
    print('client addr:', addr)  # conn连接客户端

    while True:
        data = conn.recv(1024)  # 接收
        if not data:  # 客户端已断开
            print('客户端断开连接')
            break

        print('收到的命令:', data.decode("utf-8"))
        op = ''
        try:
            op, filename = data.decode('utf-8').split(' ')
            filePath = dirPath + filename
        except :
            print('输入和文件操作无关')

        #客户下载任务
        if op == 'get':
            if os.path.isfile(filePath):  # 判断文件存在
                # 1.先发送文件大小,让客户端准备接收
                size = os.stat(filePath).st_size  # 获取文件大小
                conn.send(str(size).encode('utf-8'))  # 发送数据长度
                print('发送的大小:', size)

                # 2.发送文件内容
                conn.recv(1024)  # 接收确认
                f = open(filePath, 'rb')
                for line in f:
                    conn.send(line)  # 发送数据

                f.close()
            else:  # 文件不存在情况
                conn.send('文件不存在'.encode("utf-8"))

        #客户上传任务
        if op == 'put':
            # 1.先接收文件长度
            server_response = conn.recv(1024)
            file_size = int(server_response.decode("utf-8"))
            print('接收到的大小:', file_size)

            # 2.接收文件内容

            filename = 'new' + filename
            filePath = dirPath + filename

            f = open(filePath, 'wb')
            received_size = 0

            while received_size < file_size:
                size = 0  # 准确接收数据大小,解决粘包
                if file_size - received_size > 1024:  # 多次接收
                    size = 1024
                else:  # 最后一次接收完毕
                    size = file_size - received_size

                filedata = conn.recv(size)  # 多次接收内容,接收大数据
                filedata_len = len(data)
                received_size += filedata_len
                print('已接收:', int(received_size / file_size * 100), "%")
                f.write(filedata)
            f.close()

server.close()

客户端代码:

#encoding=utf-8

import socket
import os

client = socket.socket()  # 生成socket连接对象
ip_port = ('127.0.0.1', 9000)  # 地址和端口号
try:
    client.connect(ip_port)  # 连接
    print('服务器已连接')
except :
    print('服务器连接失败,请修改后重新运行!!')
    exit(0)

while True:
    #content = input(">>")
    content = input('请输入你要进行的文件操作:')

    if content=='exit':     #退出操作
        exit(1)

    client.send(content.encode())

    if len(content) == 0:   # 如果传入空字符继续运行
        continue

    if content.startswith("get"):       #下载任务
        client.send(content.encode("utf-8"))  # 传送和接收都是bytes类型

        # 1.先接收长度,如果接收长度报错,说明文件不存在
        server_response = client.recv(1024)
        try:
            file_size = int(server_response.decode("utf-8"))
        except:
            print('文件不存在')
            continue
        print('接收到的大小:', file_size)

        # 2.接收文件内容
        filename = 'new' + content.split(' ')[1]
        f = open(filename, 'wb')
        received_size = 0

        while received_size < file_size:
            size = 0  # 准确接收数据大小,解决粘包
            if file_size - received_size > 1024:  # 多次接收
                size = 1024
            else:  # 最后一次接收完毕
                size = file_size - received_size

            data = client.recv(size)  # 多次接收内容,接收大数据
            data_len = len(data)
            received_size += data_len
            print('已接收:', int(received_size / file_size * 100), "%")
            f.write(data)
        f.close()

    elif content.startswith('put'):          #上传任务
        op, filename = content.split(" ")

        if os.path.isfile(filename):  # 判断文件存在
            # 1.先发送文件大小,让客户端准备接收
            size = os.stat(filename).st_size  # 获取文件大小
            client.send(str(size).encode("utf-8"))  # 发送数据长度
            print('发送的大小:', size)
            # 2.发送文件内容
            f = open(filename, 'rb')
            for line in f:
                client.send(line)  # 发送数据
            f.close()
        else:  # 文件不存在情况
            print('文件不存在')  # 发送数据长度
        f.close()

    else:
        pass
client.close()

结果展示:

初始状态:

在这里插入图片描述

运行过程:

服务器端:
在这里插入图片描述
客户端:

最终结果:

在这里插入图片描述

  • 15
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值