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

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

1.实验内容

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

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

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

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

  1. 实验过程及结果
    2.1 简单的服务器端程序,能与客户端建立连接,实现像微信一样的双向通信:
import socket//导入库
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = ('192.168.146.119', 9999)//热点的ip和端口
server_socket.bind(address)
server_socket.listen()
print('服务器正在监听 {}'.format(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()

2.2 客户端的代码:
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.146.132', 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))
client_socket.close()


2.3 使用加密算法的服务端程序,实现与客户端之间的双向通信

import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = ('192.168.146.119', 9999)
server_socket.bind(address)
server_socket.listen()
print('服务器正在监听 {}'.format(address))
client_socket, addr = server_socket.accept()# 接收客户端发送的密钥
key = client_socket.recv(32)// 生成 32 字节的随机密钥
print("已接收客户端密钥")
def encrypt_message(message):
    iv = os.urandom(AES.block_size)
    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_data):
    iv = encrypted_data[:AES.block_size] 
    ciphertext = encrypted_data[AES.block_size:] // 提取密文
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = unpad(cipher.decrypt(ciphertext), AES.block_size)
    return decrypted.decode('utf-8')
try:
    while True:
        encrypted_data = client_socket.recv(1024)
        if not encrypted_data:
            break
        decrypted_msg = decrypt_message(encrypted_data)
        print(f"客户端说: {decrypted_msg}")
        reply = input("输入回复消息: ")
        encrypted_reply = encrypt_message(reply)
        client_socket.send(encrypted_reply)
except Exception as e:
    print(f"发生错误: {e}")
finally:
    client_socket.close()
    server_socket.close()
    print("服务器已关闭")

2.4 基于加密的客户端的代码

import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os
key = os.urandom(32)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('192.168.146.132', 9999))
print("已连接到服务器")
client_socket.send(key)
print("已发送密钥到服务器")
def encrypt_message(message):
    iv = os.urandom(AES.block_size) 
    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_data):
    iv = encrypted_data[:AES.block_size]
    ciphertext = encrypted_data[AES.block_size:] 
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = unpad(cipher.decrypt(ciphertext), AES.block_size)
    return decrypted.decode('utf-8')
try:
    while True:
        message = input("输入要发送的消息: ")
        encrypted_msg = encrypt_message(message)
        client_socket.send(encrypted_msg)
        encrypted_reply = client_socket.recv(1024)
        if not encrypted_reply:
            break
        decrypted_reply = decrypt_message(encrypted_reply)
        print(f"服务器回复: {decrypted_reply}")
except Exception as e:
    print(f"发生错误: {e}")
finally:
    client_socket.close()
    print("客户端已关闭")

  1. 实验过程中遇到的问题和解决过程
  • 问题1:Crypto 模块未安装导致导入 Crypto.Cipher 和 Crypto.Util.Padding时报错
  • 问题1解决方案:安装 pycryptodome 库,用命令pip install pycryptodome

其他(感悟、思考等)
Python的socket模块可以实现服务器端与客户端之间像微信一样的双向通信,很神奇。
4.参考资料
《python从入门到实践》

posted @ 2025-04-23 23:36  msksmms  阅读(48)  评论(0)    收藏  举报