20222227 实验三《Python程序设计》实验报告

20222227 2024-2025-2 《Python程序设计》实验三报告

课程:《Python程序设计》
班级: 2222
姓名: 赫连紫阳
学号:20222227
实验教师:王志强
实验日期:2025年4月16日
必修/选修: 公选课

一、实验内容

(一)实验内容

创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。

(二)实验要求

1.创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;

2.要求包含文件的基本操作,例如打开和读写操作。

3.要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中。

4.程序代码托管到码云。

注:在华为ECS服务器(OpenOuler系统)和物理机(Windows/Linux系统)上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

二、实验过程及结果

(一)通信功能实现

1.客户端相关代码:

import socket
from cryptography.fernet import Fernet
KEY = b'2DArf8mfLdgsDgwdnBQ5Uzr9zIRSEVerCnVk8Mn9xTQ='
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("127.0.0.1", 8848))
cipher = Fernet(KEY)  # 使用合法密钥初始化加密器

while True:
    message = input("输入消息:")
    encrypted_msg = cipher.encrypt(message.encode("utf-8"))  # 加密消息
    client_socket.send(encrypted_msg)
    if message == "exit":
        break
    encrypted_data = client_socket.recv(1024)
    try:
        decrypted_data = cipher.decrypt(encrypted_data).decode("utf-8")  # 解密回复
        print(f"服务器回复:{decrypted_data}")
    except:
        print("解密失败!连接已终止")
        break
client_socket.close()

客户端通信过程的逻辑如下:
客户端启动时创建Socket并连接到服务器
用户输入消息,发送至服务端
等待并显示服务器响应
通信完成
输入exit关闭Socket连接
程序结束

2.服务器相关代码

import socket
from cryptography.fernet import Fernet
KEY = b'2DArf8mfLdgsDgwdnBQ5Uzr9zIRSEVerCnVk8Mn9xTQ='
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("127.0.0.1", 8848))
server_socket.listen(5)
cipher = Fernet(KEY)
print("等待连接...")
client_socket, address = server_socket.accept()
print(f"收到来自 {address[0]}:{address[1]} 的连接")
while True:
    encrypted_data = client_socket.recv(1024)
    if not encrypted_data:
        break
    try:
        decrypted_data = cipher.decrypt(encrypted_data).decode("utf-8")  # 解密消息
    except:
        print("解密失败!连接已终止")
        break
    print(f"收到消息:{decrypted_data}")
    if decrypted_data == "exit":
        break
    reply = input("输入回复:")
    encrypted_reply = cipher.encrypt(reply.encode("utf-8"))  # 加密回复
    client_socket.send(encrypted_reply)
client_socket.close()

服务器通信过程的逻辑如下:
服务器启动,创建Socket
绑定到指定IP和端口
开始监听
当有新客户端连接时:
接受连接,返回客户端socket和地址
接收客户端选择的功能
循环接收客户端消息
打印收到的消息
等待输入回复内容
将回复发送给客户端

3.运行结果

客户端:
image

服务器:
image

(二)文件操作及加密传输

1.客户端代码

# client.py
import socket
import os
from cryptography.fernet import Fernet

KEY = b'2DArf8mfLdgsDgwdnBQ5Uzr9zIRSEVerCnVk8Mn9xTQ='
BUFFER_SIZE = 4096
SEPARATOR = "<SEPARATOR>"

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("127.0.0.1", 8080))
cipher = Fernet(KEY)


def send_file(file_path):
    try:
        file_size = os.path.getsize(file_path)
        file_name = os.path.basename(file_path)

        # 发送文件头(加密)
        header = f"FILE{SEPARATOR}{file_name}{SEPARATOR}{file_size}"
        encrypted_header = cipher.encrypt(header.encode())
        client_socket.send(encrypted_header)

        # 分块发送文件内容
        with open(file_path, "rb") as f:
            while True:
                bytes_read = f.read(BUFFER_SIZE)
                if not bytes_read:
                    break
                encrypted_data = cipher.encrypt(bytes_read)
                client_socket.send(encrypted_data)
        print(f"文件 {file_name} 发送完成")

    except Exception as e:
        print(f"文件发送失败: {str(e)}")


while True:
    message = input("输入消息(/sendfile 发送文件):")

    if message.startswith("/sendfile"):
        _, file_path = message.split(" ", 1)
        if os.path.exists(file_path):
            send_file(file_path)
        else:
            print("文件不存在")
        continue

    # 普通消息处理
    encrypted_msg = cipher.encrypt(message.encode("utf-8"))
    client_socket.send(encrypted_msg)

    if message == "exit":
        break

    # 接收回复
    encrypted_data = client_socket.recv(BUFFER_SIZE)
    try:
        decrypted_data = cipher.decrypt(encrypted_data).decode("utf-8")
        print(f"服务器回复:{decrypted_data}")
    except:
        print("解密失败!连接已终止")
        break

client_socket.close()

客户端逻辑:
输入/sendfile文件传输
输入要传输的文件名
客户端发送文件名给服务器
客户端执行文件传输:
读取文件内容
使用异或加密算法加密文件数据
发送完成后关闭写入端
接收并显示服务器响应

2.服务器代码:

# server.py
import socket
import os
from cryptography.fernet import Fernet

KEY = b'2DArf8mfLdgsDgwdnBQ5Uzr9zIRSEVerCnVk8Mn9xTQ='
BUFFER_SIZE = 4096
SEPARATOR = "<SEPARATOR>"
SAVE_PATH = "received_files"

# 创建保存目录
os.makedirs(SAVE_PATH, exist_ok=True)

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("127.0.0.1", 8080))
server_socket.listen(5)
cipher = Fernet(KEY)

print("等待连接...")
client_socket, address = server_socket.accept()
print(f"收到来自 {address[0]}:{address[1]} 的连接")


def save_file(file_name, file_size):
    save_path = os.path.join(SAVE_PATH, file_name)
    bytes_received = 0

    with open(save_path, "wb") as f:
        while bytes_received < file_size:
            encrypted_data = client_socket.recv(BUFFER_SIZE)
            decrypted_data = cipher.decrypt(encrypted_data)
            f.write(decrypted_data)
            bytes_received += len(decrypted_data)
    print(f"文件 {file_name} 保存成功 ({bytes_received} bytes)")


while True:
    encrypted_data = client_socket.recv(BUFFER_SIZE)
    if not encrypted_data:
        break

    try:
        decrypted_data = cipher.decrypt(encrypted_data).decode("utf-8")
    except:
        print("解密失败!连接已终止")
        break

    # 文件传输处理
    if decrypted_data.startswith("FILE"):
        _, file_name, file_size = decrypted_data.split(SEPARATOR)
        file_size = int(file_size)
        print(f"正在接收文件: {file_name} ({file_size} bytes)")
        save_file(file_name, file_size)
        continue

    # 普通消息处理
    print(f"收到消息:{decrypted_data}")

    if decrypted_data == "exit":
        break

    reply = input("输入回复:")
    encrypted_reply = cipher.encrypt(reply.encode("utf-8"))
    client_socket.send(encrypted_reply)

client_socket.close()

服务器逻辑:
服务器启动,创建Socket
绑定到指定IP和端口
当有新客户端连接时:
接受连接,返回客户端socket和地址
接收文件名
接收加密文件数据
发送操作结果给客户端

3.运行结果
客户端:
image

服务器:
image

文件内容:
image

(三)上传代码至码云

https://gitee.com/hlzy2004/python/tree/master/

image

三、实验过程中遇到的问题和解决过程
问题1:无法安装cryptography库

问题1解决方案:按照报错中提示的步骤更新

实验感悟
本次实验围绕网络通信与数据安全展开,通过Python实现了加密消息传输及文件传输功能,主要收获如下:
网络编程基础:深入理解了TCP协议的通信流程,掌握了socket库的使用方法,包括绑定端口、监听连接、数据收发等核心操作。
加密技术应用:通过cryptography库实践了对称加密的实现,认识到加密算法在保障通信安全中的重要性。
文件传输设计:扩展了基础通信功能,实现了文件的分块加密传输,学习如何通过协议头(如FILE)区分消息类型,并处理大文件的读写与网络传输边界问题。

本次实验不仅巩固了网络编程与加密技术的基础知识,更培养了问题分析与解决能力。通过逐步迭代功能(从基础通信→加密→文件传输),体会了模块化开发的重要性。未来可在此基础上探索更复杂的应用场景(如P2P通信、分布式文件传输),持续提升工程实践能力。

参考资料
深入理解Python密码学:使用PyCrypto库进行加密和解密
python 对文件进行异或运算

posted @ 2025-04-23 15:15  望舒、  阅读(52)  评论(0)    收藏  举报