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

20242327 2024-2025-2 《Python程序设计》实验3报告

课程:《Python程序设计》
班级: 2423
姓名: 梁瑞丽
学号: 20242327
实验教师:王志强
实验日期:2025年4月17日
必修/选修: 公选课

1.实验内容

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

2. 实验过程及结果

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

如下是服务端的代码实现:

import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# address = ('172.20.10.2', 9999)
address = ('172.20.10.2', 9999)
#绑定
server_socket.bind(address)
#监听
server_socket.listen(5)
print("开始监听....",address)
#accecpt
client_socket, address = server_socket.accept()
print("我们收到{}的连接".format(address))
while True:
    data = client_socket.recv(1024)
    if not data:
        break
    print("客户端说:{}".format(data.decode("utf-8")))
    client_socket.send(input("服务端回应:").encode("utf-8"))
#关闭连接
client_socket.close()

如下是客户端的代码实现:

import socket

#新建Socket,实例化
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#连接服务器
client_socket.connect(('172.20.10.3', 9999))
# client_socket.connect(('localhost', 9999))
while True:
    client_socket.send(input("客户端说:").encode("utf-8"))
    data = client_socket.recv(1024)
    print("服务端回答:",data.decode("utf-8"))

client_socket.close()

在实现与我的搭档进行“打电话”过程中,我们首先在 Windows 命令提示符中通过 ipconfig 命令获取的网络配置信息。并选择使用其中的 IPv4 地址来进行网络通信如下图:


(2)实现文件的基本操作,例如打开和读写操作。

通过了解相关知识,我知道了在Python中,使用open()函数打开文件,其中open()函数的第一个参数是文件名;同时可以使用使用write()方法写入单行内容。如下是接收端和客户端分别加入文件操作功能后的代码实现。特别声明,本部分代码相当内容依靠大模型的打磨,本人代码基本100%不靠谱。
以下是服务端代码:

import socket

# 创建服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定地址和端口
address = ('localhost', 9999)
server_socket.bind(address)

# 开始监听
server_socket.listen(5)
print("开始监听...", address)

# 接受客户端连接
client_socket, client_address = server_socket.accept()
print("我们收到{}的连接".format(client_address))

# 打开文件用于保存接收的数据
with open("received_file.txt", "w", encoding="utf-8") as file:
    while True:
        data = client_socket.recv(1024)
        if not data:
            break
        print("客户端说:{}".format(data.decode("utf-8")))
        # 将接收到的数据写入文件
        file.write(data.decode("utf-8") + "\n")
        # 向客户端发送确认信息
        client_socket.send(input("服务端说:").encode("utf-8"))

# 关闭连接
client_socket.close()
server_socket.close()

以下是客户端代码:

import socket

# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接到服务器
server_address = ('localhost', 9999)
client_socket.connect(server_address)

while True:
    # 发送消息给服务器
    message = input('请输入要发送给服务器的消息: ')
    client_socket.send(message.encode('utf-8'))

    # 接收服务器消息
    data = client_socket.recv(1024).decode('utf-8')
    if not data:
        break
    print('服务器说: {}'.format(data))

    # 检测是否需要进行文件操作
    if data.lower().startswith("file:"):
        # 提取文件操作指令
        file_command = data.split(":")[1].strip()
        if file_command.startswith("read"):
            # 读取文件
            file_path = file_command.split()[1]
            try:
                with open(file_path, 'r', encoding='utf-8') as file:
                    file_content = file.read()
                    print(f"文件内容:\n{file_content}")
            except FileNotFoundError:
                print("文件未找到!")
            
        elif file_command.startswith("write"):
            # 写入文件
            file_path, content = file_command.split()[1], " ".join(file_command.split()[2:])
            try:
                with open(file_path, 'w', encoding='utf-8') as file:
                    file.write(content)
                print("文件写入成功!")
            except Exception as e:
                print(f"写入文件时发生错误:{e}")
       

# 关闭连接
client_socket.close()

实现如下图:



注:截图中部分文件与此代码无关,为之前测试时一些“报废”文件。

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

根据老师群里发送的AES(高级加密标准)算法,将密钥和初始化向量(IV)在发送方和接收方调整保持一致,并结合前置代码,服务端和客户端代码分别如下。
服务端代码:

import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

# 创建服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定地址和端口
address = ('localhost', 9999)
server_socket.bind(address)

# 开始监听
server_socket.listen()
print("服务器正在监听端口 9999...")

try:
    # 接收客户端连接
    conn, addr = server_socket.accept()

    # 接收加密数据
    encrypted_data = conn.recv(4096)  # 根据需要调整接收缓冲区大小
    print("接收到加密数据,开始解密...")

    # AES 加密参数
    key = b'1234567890987654'  # 16 字节密钥
    iv = b'1234567890987654'  # 初始化向量

    # 创建 AES 解密器
    cipher = AES.new(key, AES.MODE_CBC, iv=iv)
    decrypted_data = cipher.decrypt(encrypted_data)

    # 去除填充
    try:
        decrypted_data = unpad(decrypted_data, AES.block_size)
    except ValueError as e:
        print(f"解密失败:{e}")
        decrypted_data = "解密失败".encode("utf-8")  # 使用 UTF-8 编码将字符串转换为 bytes

    # 保存解密后的数据到文件
    with open("decrypted_output.txt", "wb") as f:
        f.write(decrypted_data)

    print("解密完成,数据已保存到 decrypted_output.txt")
finally:
    # 关闭服务器套接字
    server_socket.close()

以下是客户端代码:

import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

# 创建客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 定义服务器地址和端口
server_address = ('localhost', 9999)

# 连接到服务器
client_socket.connect(server_address)
print("已连接到服务器")

# AES 加密参数
key = b'1234567890987654'  # 16 字节密钥
iv = b'1234567890987654'  # 初始化向量

# 读取文件内容
with open("input.txt", "rb") as f:
    data = f.read()

# 创建 AES 加密器
cipher = AES.new(key, AES.MODE_CBC, iv=iv)

# 对数据进行加密,确保数据长度是块大小的倍数
padded_data = pad(data, AES.block_size)
encrypted_data = cipher.encrypt(padded_data)

# 发送加密数据
client_socket.sendall(encrypted_data)
print("加密数据已发送到服务器")

# 关闭客户端套接字
client_socket.close()

运行结果如下:



(4)程序代码托管到码云。

3. 实验过程中遇到的问题和解决过程

  • 问题1:程序报错提示“每个套接字地址(协议/网络地址/端口)只允许使用一次。”

  • 问题1解决方案:通过询问大模型,它给出了如下回答:

    根据它的提示,这个问题被解决。

  • 问题2:在进行加密解密的实现过程中,由于对Python语言的不熟悉以及对加解密流程不熟悉,在运行时出现如下报错:

  • 问题2解决方案:
    Kimi对于这个情况的回答如下:

    手动修改IV后,这个问题被解决,文件可以正确的加密解密。

其他(感悟、思考等)

在本次实验过程中,尽管完成了很多功能的实现,但大多数还是依靠老师课堂上的示范以及向大模型的求助,只有在一些简单的地方我才有信心去写,这让我有很强烈的挫败感(尤其我写的总是不对啊喂)。这门课的学习即将走向尾声,对于自己在Python学习上的懈怠,我追悔莫及,为了弥补编程能力的欠缺,在最终的实验四前,我将多多学习。

参考资料

《零基础学Python》

posted @ 2025-04-20 13:22  小鱼爱大葱  阅读(66)  评论(1)    收藏  举报