20241114 陈飞达 《Python程序设计》实验三报告

20241114 陈飞达 《Python程序设计》实验三报告

课程:《Python程序设计》
班级: 2411
姓名: 陈飞达
学号:20241114
实验教师:王志强
实验日期:2025年4月16日
必修/选修: 公选课

(一)实验内容和要求

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

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

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

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

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

(二)实验过程和结果

首先根据课上学的知识写一段最基础的、可以完成通信功能的客户端和服务器程序:

客户端:

import socket

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

# 连接到服务器
server_address = ('172.16.219.51', 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 (input("是否继续Y/N?")=="N"):
    #     break

# 关闭连接
client_socket.close()

服务器:

import socket

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

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

# 监听连接
server_socket.listen(1)
print('服务器正在监听 {}:{}'.format(*server_address))

# 接受客户端连接
client_socket, client_address = server_socket.accept()
print('接受来自 {} 的连接'.format(client_address))

while True:
    # 接收客户端消息
    data = client_socket.recv(1024).decode('utf-8')
    if not data:
        break
    print('客户端说: {}'.format(data))

    # 发送消息给客户端
    message = input('请输入要发送给客户端的消息: ')
    client_socket.send(message.encode('utf-8'))
    if input("是否要继续?Y/N")=="N":
        break

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

这样,我们可以同自己及小组中的另一个人进行通信:

这样就完成了第一个任务。

接下来,我在想如何能上传打开文件呢?加密又该怎么做?

这个时候,一个名为os的库出现在我的眼前。

我在csdn上找到了一篇绝赞的博客,里面详细介绍了os库的各种用途,可以比较容易地创建、打开、保存文件。

而后,对于加密这一部分,我想的是直接用恺撒加密,但是这个方向有一个很大的问题——我们主要使用中文,一个英文、数字的加密意义不大。

于是,当我寻找其他的可以加密中文的加密方法时,AES给了我很大的帮助。

所以,我们两个人根据以上的两篇博客完成了这个实验的大部分内容。

具体的代码如下:

客户端:

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

# 密钥和初始化向量,需和服务端保持一致
key = b'Sixteen byte key'
iv = b'InitializationVe'

def aes_encrypt(data):
    try:
        cipher = AES.new(key, AES.MODE_CBC, iv)
        padded_data = pad(data.encode('utf-8'), AES.block_size)
        encrypted_data = cipher.encrypt(padded_data)
        return encrypted_data
    except Exception as e:
        print(f"加密过程出错: {e}")
        return None

server_address = ('172.16.227.143', 8888)
file_name = 'send_file.txt'
log_file = 'client_log.txt'
client_socket = None

try:
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(server_address)

    use_existing_file = input("是否使用已有的文件?(Y/N): ").strip().upper()
    script_dir = os.path.dirname(os.path.abspath(__file__))

    if use_existing_file == 'Y':
        file_path = os.path.join(script_dir, file_name)
        if not os.path.exists(file_path):
            print(f"文件 {file_name} 不存在,将创建新文件并提示输入内容。")
            use_existing_file = 'N'
    if use_existing_file == 'N':
        file_path = os.path.join(script_dir, file_name)
        print("\n请输入要发送的内容(输入空行结束):")
        content = []
        while True:
            line = input()
            if not line:
                break
            content.append(line)
        content = '\n'.join(content)
        with open(file_path, 'w', encoding='utf-8') as file:
            file.write(content)
        print(f"内容已保存到 {file_name}")

    with open(file_path, 'r', encoding='utf-8') as file:
        plaintext_data = file.read()

    encrypted_data = aes_encrypt(plaintext_data)
    if encrypted_data is None:
        raise ValueError("加密失败,无法继续执行。")

    with open(log_file, 'w', encoding='utf-8') as log:
        log.write("加密前的内容:\n")
        log.write(plaintext_data)
        log.write("\n\n加密后的内容:\n")
        log.write(encrypted_data.hex())

    confirm = input("\n是否发送文件内容?(Y/N): ").strip().upper()
    if confirm == 'Y':
        client_socket.send(encrypted_data)
        print('数据已加密并发送')
    else:
        print("发送已取消。")

except ConnectionRefusedError:
    print("无法连接到服务器,请检查服务端是否启动。")
except FileNotFoundError:
    print("文件未找到,请检查文件路径。")
except Exception as e:
    print(f"发生未知错误: {e}")
finally:
    if client_socket:
        client_socket.close()

服务器:

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

# 密钥和初始化向量,需和客户端保持一致
key = b'Sixteen byte key'
iv = b'InitializationVe'

def aes_decrypt(encrypted_data):
    try:
        cipher = AES.new(key, AES.MODE_CBC, iv)
        decrypted_data = cipher.decrypt(encrypted_data)
        unpadded_data = unpad(decrypted_data, AES.block_size)
        return unpadded_data.decode('utf-8')
    except Exception as e:
        print(f"解密过程出错: {e}")
        return None

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('172.16.219.51', 8888)
log_file = 'server_log.txt'
client_socket = None

try:
    server_socket.bind(server_address)
    server_socket.listen(1)
    print(f'服务器正在监听 {server_address[0]}:{server_address[1]}')

    client_socket, client_address = server_socket.accept()
    print(f'接受来自 {client_address} 的连接')

    encrypted_data = client_socket.recv(4096)
    decrypted_data = aes_decrypt(encrypted_data)
    if decrypted_data is None:
        raise ValueError("解密失败,无法继续执行。")

    with open(log_file, 'w', encoding='utf-8') as log:
        log.write("接收到的加密内容:\n")
        log.write(encrypted_data.hex())
        log.write("\n\n解密后的内容:\n")
        log.write(decrypted_data)

    script_dir = os.path.dirname(os.path.abspath(__file__))
    file_path = os.path.join(script_dir, 'received_file.txt')
    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(decrypted_data)
    print('数据已解密并保存到 received_file.txt')

except OSError as e:
    print(f"服务器绑定或监听时出现错误: {e}")
except FileNotFoundError:
    print("文件未找到,请检查文件路径。")
except Exception as e:
    print(f"发生未知错误: {e}")
finally:
    if client_socket:
        client_socket.close()
    if server_socket:
        server_socket.close()

以下是测试的结果:




最后是上传至码云:


码云链接:

https://gitee.com/fida1214/python-programming-assignment/blob/master/client2.py

https://gitee.com/fida1214/python-programming-assignment/blob/master/server2.py

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

问题一:在进行不同计算机之间的通信时,显示“目标计算机积极防御”。

问题一解决方案:询问王老师,关闭防火墙即可。

问题二:用凯撒加密只能加密英文,而不能加密中文。

问题二解决方案:在CSDN中找到AES相关的博客,学习使用AES加密。

其他(感悟、思考等)

完成这个实验是相当困难的,尤其是面对许多闻所未闻的东西。但是,面对如此困难的局面,好友的协助与CSDN上的博客给了我莫大的帮助,能完成这一次的实验,我成就感满满,相信在未来,面对更多的困难的时候,一定会很自信。

参考资料

os库使用:https://blog.csdn.net/yw1013/article/details/134093810?ops_request_misc

凯撒加密:https://blog.csdn.net/libaiup/article/details/135978923?ops_request_misc

AES加密:https://blog.csdn.net/SPESEG/article/details/143602811?ops_request_misc

posted @ 2025-04-22 22:53  陈飞达  阅读(44)  评论(0)    收藏  举报