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

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

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

1.实验内容

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

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

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

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

2. 实验过程及结果

  1. 通过学习socket的使用,尝试本机相互通讯

  2. 加入文件读写功能




  3. 引入pycryptodome对传入传出的文件进行加解密

  4. 切换socket.bind后加的IP以及端口,向其他主机进行通信(提前确保key和iv一致)

  5. 代码托管到gittee

  • 服务端代码:
import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64

Key = b'1234567890123456'
iv = b'1234567890123456'

def encrypt(plain_text, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_text = pad(plain_text.encode(), AES.block_size)
    encrypted_text = cipher.encrypt(padded_text)
    return base64.b64encode(encrypted_text).decode()

def decrypt(encrypted_text, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted_text = unpad(cipher.decrypt(base64.b64decode(encrypted_text)), AES.block_size)
    return decrypted_text.decode()

# 创建服务器 socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = ('localhost', 1234)
s.bind(address)
s.listen(5)
print("服务器启动,等待{}连接...".format(address))

# 接受连接
c, addr = s.accept()
print("我们收到了{}的连接".format(addr))

with open("server_output.txt", "w", encoding="utf-8") as f:
    while True:
        # 接收数据
        data = c.recv(1024).decode("utf-8")
        if not data:
            break

        # 解密数据
        try:
            decrypted_text = decrypt(data, Key, iv)
            print("服务端收到:{}".format(decrypted_text))
            f.write(decrypted_text + "\n")
            f.flush()
        except Exception as e:
            print(f"解密失败:{e}")
            break

        # 获取服务端回应,加密后发送
        response = input("服务端回应:")
        encrypted_response = encrypt(response, Key, iv)
        c.send(encrypted_response.encode("utf-8"))

        # 是否继续
        if input("是否继续?(y/n):") == 'n':
            break

c.close()
s.close()

= 用户端代码:

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

Key = b'1234567890123456'
iv = b'1234567890123456'

def encrypt(plain_text, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_text = pad(plain_text.encode(), AES.block_size)
    encrypted_text = cipher.encrypt(padded_text)
    return base64.b64encode(encrypted_text).decode()

def decrypt(encrypted_text, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted_text = unpad(cipher.decrypt(base64.b64decode(encrypted_text)), AES.block_size)
    return decrypted_text.decode()

# 创建客户端 socket
t = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = ('localhost', 1234)
t.connect(address)

# 从文件读取并发送数据
with open("client_input.txt", "r", encoding="utf-8") as f:
    for line in f:
        text = line.strip()
        if not text:
            continue

        # 加密并发送
        encrypted_text = encrypt(text, Key, iv)
        t.send(encrypted_text.encode("utf-8"))

        # 接收服务端回应并解密
        response = t.recv(1024).decode("utf-8")
        decrypted_response = decrypt(response, Key, iv)
        print("服务端回应:", decrypted_response)

        if input("是否继续发送?(y/n):").lower() == 'n':
            break

t.close()

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

  • 问题1:文件传输过程中出现长时间卡顿
  • 问题1解决方案:软教网络不稳定,更换网络后解决
  • 问题2:文件解密失败
  • 问题2解决方案:由于使用了AES-CBC进行加解密,使得明文长度产生限制,在修改传入数据后成功。

其他(感悟、思考等)

计算机网络的相互通信并没有什么复杂的逻辑,但是经过不断的扩展、延申,最终却构成了我们今天无比辉煌的计算机网络;许多伟大的成就都有一个渺小的开始,我们也应该怀着永不放弃的决心,不断提升自己,积微成著。

参考资料

posted @ 2025-04-21 07:31  好巧哦  阅读(18)  评论(0)    收藏  举报