m0_69950967 2023-09-27 22:17 采纳率: 50%
浏览 7
已结题

下载不了文件网络安全编程文件的上传下载,结合用户,要结合TCP 粘包问题,使用struct模块解决认证,传递的所有信息尽量是json格式(文件传输)

server.py


import socket
import json
import os.path

# 创建socket对象
sk = socket.socket()
# 绑定IP地址和端口号
sk.bind(('127.0.0.1', 8001))
# 监听连接请求
sk.listen()

while True:
    # 接受客户端的连接请求
    conn, addr = sk.accept()

    # 用户认证
    authenticated = False
    while not authenticated:
        # 接收用户名和密码
        username = conn.recv(1024).decode('utf-8')
        password = conn.recv(1024).decode('utf-8')

        # 假设这里是一个用户验证函数,根据用户名和密码判断用户是否合法
        users = {
            "user1": "password1",
            "user2": "password2",
            "user3": "password3"
        }

        if username in users and users[username] == password:
            authenticated = True
            # 发送认证成功的消息给客户端
            conn.send("Authentication successful".encode('utf-8'))
        else:
            # 发送认证失败的消息给客户端
            conn.send("Authentication failed".encode('utf-8'))

    # 接收客户端的请求类型
    request_type = conn.recv(1024).decode('utf-8')

    if request_type == 'upload':
        # 接收文件的元数据信息
        str_dic = conn.recv(1024).decode('utf-8')
        dic = json.loads(str_dic)

        # 接收文件内容并写入文件
        with open(dic['filename'], 'wb') as f:
            filesize_left = dic['filesize']
            while filesize_left > 0:
                content = conn.recv(min(filesize_left, 1024))
                f.write(content)
                filesize_left -= len(content)

        # 发送文件上传成功的消息给客户端
        conn.send("File uploaded successfully".encode('utf-8'))
        print(f"File '{dic['filename']}' uploaded successfully")

    elif request_type == 'download':
        # 接收要下载的文件路径
        file_path = conn.recv(1024).decode('utf-8')

        if not os.path.isfile(file_path):
            # 发送文件不存在的消息给客户端
            conn.send("File does not exist".encode('utf-8'))
        else:
            # 发送文件的元数据信息
            filesize = os.path.getsize(file_path)
            dic = {'filename': os.path.basename(file_path), 'filesize': filesize}
            str_dic = json.dumps(dic)
            conn.send(str_dic.encode('utf-8'))

            # 发送文件内容
            with open(file_path, 'rb') as f:
                while True:
                    content = f.read(1024)
                    if not content:
                        break
                    conn.sendall(content)

            # 发送文件下载成功的消息给客户端
            conn.send("File downloaded successfully".encode('utf-8'))
            print(f"File '{file_path}' downloaded successfully")

    # 关闭连接
    conn.close()
sk.close()

client.py


import socket
import json
import os.path

# 创建socket对象
sk = socket.socket()
# 连接服务器
sk.connect(('127.0.0.1', 8001))

# 用户认证
authenticated = False
while not authenticated:
    # 输入用户名和密码
    username = input("Username: ")
    password = input("Password: ")

    # 发送用户名和密码给服务器
    sk.sendall(username.encode('utf-8'))
    sk.sendall(password.encode('utf-8'))

    # 接收服务器返回的认证结果
    response = sk.recv(1024).decode('utf-8')
    print(response)

    if response == "Authentication successful":
        authenticated = True

# 文件上传或下载
while True:
    action = input("Enter 'upload' to upload a file or 'download' to download a file (or 'exit' to quit): ")

    if action == 'upload':
        # 输入要上传的文件路径
        file_path = input("Enter the path of the file to upload: ")

        if not os.path.isfile(file_path):
            print("File does not exist")
            continue

        # 获取文件大小和文件名,并构造元数据信息
        filesize = os.path.getsize(file_path)
        dic = {'filename': os.path.basename(file_path), 'filesize': filesize}
        str_dic = json.dumps(dic)

        # 发送请求类型和元数据信息给服务器
        sk.sendall(action.encode('utf-8'))
        sk.sendall(str_dic.encode('utf-8'))

        # 发送文件内容
        with open(file_path, 'rb') as f:
            while True:
                content = f.read(1024)
                if not content:
                    break
                while content:
                    sent = sk.send(content)
                    content = content[sent:]

        print(sk.recv(1024).decode('utf-8'))

    elif action == 'download':
        # 输入要保存下载文件的路径
        file_path = input("Enter the path to save the downloaded file: ")

        # 发送请求类型和要下载的文件路径给服务器
        sk.sendall(action.encode('utf-8'))
        sk.sendall(file_path.encode('utf-8'))

        # 接收服务器返回的消息
        response = sk.recv(1024).decode('utf-8')
        if response == "File does not exist":
            print(response)
            continue

        # 接收文件的元数据信息
        str_dic = sk.recv(1024).decode('utf-8')
        dic = json.loads(str_dic)

        # 接收文件内容并写入文件
        with open(file_path, 'wb') as f:
            filesize_left = dic['filesize']
            while filesize_left > 0:
                content = sk.recv(min(filesize_left, 1024))
                f.write(content)
                filesize_left -= len(content)

        print(sk.recv(1024).decode('utf-8'))

    elif action == 'exit':
        break

# 关闭连接
sk.close()

img


客户端出现错误

Traceback (most recent call last):
  File "D:\python\PYTHON项目\client.py", line 77, in <module>
    dic = json.loads(str_dic)
          ^^^^^^^^^^^^^^^^^^^
  File "D:\python\python3.11.4\Lib\json\__init__.py", line 346, in loads
    return _default_decoder.decode(s)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\python\python3.11.4\Lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\python\python3.11.4\Lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

进程已结束,退出代码为 1

但在服务端出现

img

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 10月5日
    • 修改了问题 9月28日
    • 创建了问题 9月27日