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

课程:《Python程序设计》
班级: 2421
姓名: 庞耀
学号:20242120
实验教师:王志强
实验日期:2025年4月16日
必修/选修: 公选课

1.实验内容

通过Socket套接字技术,创建客户端与服务端,实现以下功能:
(1)用Python语言编程实现通信演示实例并演示
(2)添加文件的打开,关闭等基本操作,发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中
(3)实验代码上传到码云

2. 实验过程及结果

(1)Socket创建客户端服务端的简单样例:
导入socket库
创建一个socket套接字
与同桌连接同一局域网,在终端中输入ipconfig找到两台电脑的ip地址

输入ip及端口号
开始运行
以下是代码及运行结果:
服务端:

import socket
server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
address=('192.168.43.108',9999)
server_socket.bind(address)
server_socket.listen(5)
client_socket,client_address=server_socket.accept()
while True:
    data=client_socket.recv(1024).decode("utf-8")
    if not data:
        break
    print(f"李映亮说:{data}")
    client_socket.send(input("庞耀回应:").encode("utf-8"))
client_socket.close()

客户端:

import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("192.168.43.228", 9999))
while True:
        msg = input("庞耀说:")
        client_socket.send(msg.encode('utf-8'))
        if msg.lower() == 'q':
            break
        data = client_socket.recv(1024)
        print("李映亮回答:", data.decode('utf-8'))
client_socket.close()

实验结果:


(2)socket实现文件加密传输:
使用了AES-CBC模式加密,为了方便演示,代码中固定了IV
创建socket套接字
编写了一个文件函数,注意区分客户端为'r'(读取已经写好的文件),服务端为'w',将传输数据写入新文件
以下是代码及运行结果:
服务端:

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

key = b'2cbed40efc5cd05b5eddd706d0e1265f'
iv = bytes.fromhex('2cbed40efc5cd05b5eddd706d0e1265f')

def encrypt_message(message):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted = cipher.encrypt(pad(message.encode('utf-8'), AES.block_size))
    return iv + encrypted

def decrypt_message(encrypted_message):
    iv = encrypted_message[:AES.block_size]
    encrypted = encrypted_message[AES.block_size:]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = unpad(cipher.decrypt(encrypted), AES.block_size)
    return decrypted.decode('utf-8')

def save_file(filename, data):
    with open(filename, 'w', encoding='utf-8') as f: 
        f.write(data)
    print(f"文件{filename}已保存")

def start_server(port=9999):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(("192.168.43.108", port))
    server_socket.listen(5)
    print(f"[*] 正在监听端口 {port}...")

    client_socket, client_address = server_socket.accept()
    print(f"[+] 连接来自:{client_address}")

    try:
        encrypted_data = b''
        while True:
            chunk = client_socket.recv(4096)
            if not chunk:
                break
            encrypted_data += chunk

        decrypted_data = decrypt_message(encrypted_data)
        save_file("received_file.txt", decrypted_data)  

    except ValueError as e:
        print(f"解密失败: {e}")
    finally:
        client_socket.close()
        server_socket.close()

start_server()

客户端:

import os
import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
key = b'2cbed40efc5cd05b5eddd706d0e1265f'
iv = bytes.fromhex('2cbed40efc5cd05b5eddd706d0e1265f')

def encrypt_message(message):
    if isinstance(message, bytes):
        data = message
    else:
        data = message.encode('utf-8')
    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted = cipher.encrypt(pad(data, AES.block_size))
    return iv + encrypted


def send_file(filename, host, port):
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect((host, port))

    try:
        with open(filename, 'rb') as f:
            plaintext = f.read()

        encrypted_data = encrypt_message(plaintext)

        client_socket.sendall(encrypted_data)
        print(f"[+] 文件 {filename} 已加密发送")

    finally:
        client_socket.close()
if __name__ == "__main__":
    import sys

    if len(sys.argv) > 1 and sys.argv[1] == "server":
        print("请运行服务器端代码文件来启动服务器。")
    else:
        file_to_send = input("请输入要发送的文件路径: ")
        send_file(file_to_send, "192.168.43.108", 9999)

实验结果:

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

  • 问题1:学习Python的过程中没有接触过文件操作

  • 问题1解决方案:参考了书籍《Python编程从入门到实践》,了解到除了用上述代码中的方法,还可以导入pathlib库,用库中的函数解决问题

  • 问题2:不理解AES-CBC加密方法

  • 问题2解决方案:询问了DeepSeek,其加密的大致流程如下
    发送方(客户端):
    输入明文消息 → 编码为字节 → 填充至16字节倍数 → 用AES-CBC加密 → 发送IV + 密文
    接收方(服务端):
    接收IV + 密文 → 分离IV和密文 → 用AES-CBC解密 → 去除填充 → 解码为字符串 → 保存文件

  • ...

其他(感悟、思考等)

本次实验成功使用socket套接字实现了客户端与服务端的基本连接和文件加密传输
学习了文件操作的基本方式以及AES-CBC加密方法,巩固了Python函数的使用方法

参考资料

posted @ 2025-04-20 11:09  light-py  阅读(33)  评论(0)    收藏  举报