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

课程:《Python程序设计》
班级: 2021
姓名: 张权城
学号:20202107
实验教师:王志强
实验日期:2022年4月21日
必修/选修: 公选课

1.实验内容

创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
要求:
(1)创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;
(2)要求包含文件的基本操作,例如打开和读写操作。
(3)要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中。
(4)程序代码托管到码云。

2. 实验过程及结果

(1)设计思路

该实验目标是制作一个基于socket的通讯器,根据之前课上学习的内容及课后作业,本次实验不难完成。
加密上选择的是基于pyDes的CBC模式DES加密,实现了客服端与服务器的双向加密通信。基于Python标准库tkinter,实现了可视化选择目标文件的功能。但由于没有具体实现tkinter窗体(极其不标准的使用方法),导致使用该功能后会有一个无内容的tkinter窗体残留,虽然不影响总体使用,但对程序的完成性和一致性有所破坏。

(2)主要代码介绍

部分代码有参考。
报告中只贴出了部分代码,全部代码已上传码云:服务器部分客户端部分DES加解密部分

  • 加解密部分:
    基于pyDes库实现DES加解密功能。
from pyDes import des, CBC, PAD_PKCS5
import binascii
key_ = '12345675'
def des_encrypt(s):
    """
    DES 加密
    :param s: 原始字符串
    :return: 加密后字符串,16进制
    """
    secret_key = key_
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    en = k.encrypt(s, padmode=PAD_PKCS5)
    return binascii.b2a_hex(en)
def des_descrypt(s):
    """
    DES 解密
    :param s: 加密后的字符串,16进制
    :return:  解密后的字符串
    """
    secret_key = key_
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5)
    return de
  • 客户端部分:
    循环发送字符串给服务器。取'close_'作为关闭连接的保留字。
import socket
from mydes import des_descrypt, des_encrypt
from tkinter.filedialog import askopenfilename
if __name__ == '__main__':
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1', 8001))
    print('连接服务器成功')
    while True:
        ch = input('1.发送字符串 2.发送文件 3.退出\n请选择想要使用的功能:')
        if ch == '1':
            str_ = input('请输入要传输的内容:')
        elif ch == '2':
            filename = askopenfilename()
            with open(filename, 'r', encoding='utf-8') as f:
                str_ = f.read()
        elif ch == '3':
            str_ = 'close_'
            str_ = des_encrypt(str_)
            s.sendall(str_)
            break
        else:
            print('无该选项,请重新输入')
        str_ = des_encrypt(str_)
        # print(type(str_))
        s.sendall(str_)
        data = s.recv(1024)
        data = des_descrypt(data)
        print(data.decode())
    s.close()
    print('连接已关闭')
  • 服务器部分:
    循环接收客户端发送的数据,并写入文件中。取'close_'作为关闭连接的保留字。
import socket
from mydes import des_descrypt, des_encrypt


if __name__ == '__main__':
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('127.0.0.1', 8001))
    print('服务器已创建,正在监听中...')
    s.listen()
    conn, address = s.accept()
    while True:
        data = conn.recv(1024)
        data = des_descrypt(data)
        # print(data, type(data))
        if data == b'close_':
            break
        else:
            with open('received', 'wb') as f:
                f.write(data)
            str_ = '服务器已接收:'+str(data)
            str_ = des_encrypt(str_.encode())
            conn.sendall(str_)
            print('接收数据:', data.decode(), '\n已写入received.txt文件中')
    s.close()
    print('服务器关闭')

(4)程序结果

客户端:

  • 发送字符串:
  • 发送文件
  • 结束连接

    服务器:

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

暂无。

其他(感悟、思考等)

socket编程是我以前没有涉及过的领域,在python课上能够学到很多实用的知识,拓宽我的视野让我受益良多。

 

码云链接:https://gitee.com/zhang-quancheng-2107/zqc.python.test.git