zoukankan      html  css  js  c++  java
  • 20201215 王馨瑶 2019-2020-2 《Python程序设计》实验三报告

    学号 2019-2020-2 《Python程序设计》实验x报告

    课程:《Python程序设计》
    班级: 2012
    姓名: 王馨瑶
    学号:20201215
    实验教师:王志强
    实验日期:2020年5月24日
    必修/选修: 公选课

    1.实验内容

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

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

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

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

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

    2. 实验过程及结果

    a.服务端监听多个客户端

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('127.0.0.1', 8001))
    s.listen(5)
    socks = []  # 存放每个客户端的socket
    

    b.客户端进行连接

    amanda = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    amanda.connect(('127.0.0.1', 8001))  # 建立连接,参数必须是元组的形式
    print(amanda.recv(1024))  # 接收welcome!
    

    c.客户端实现循环互动

    while True:
        fun = input("Input your choice:")
        amanda.sendall(fun.encode())
        if fun == 'end':
            print("Ok,Bye!")
            break
        elif fun == 'encrypt file':
            filename = input("Please Input the file name which you want to encrypt:")
            with open(filename, 'w')as file:
                content = input("please input the content of " + filename + ':')
                try:
                    file.writelines(content)
                finally:
                    file.close()
            af_filename = 'encrypted.txt'
            amanda.sendall(af_filename.encode())
            # amanda.sendall('amanda'.encode())
            encrypt(filename, af_filename)
            send_out(af_filename)
    

    d.加密文件

    在这里插入图片描述

    第一次正儿八经接触密码学。查阅资料后决定用Python实现AES中相对简单的ECB模式加密。

    需要了解补位知识、base64编码、utf-8编码等等

    加密函数:

    def encrypt(filename,af_filename):
        key = input("Please set a key:")
        data = str(open(filename, 'rb').read())
        open(filename, 'rb').close()
        key = key.encode('utf8')
        data = pad(data)
        cipher = AES.new(key, AES.MODE_ECB)
        # 加密后得到的是bytes类型的数据,使用Base64进行编码,返回byte字符串
        result = cipher.encrypt(data.encode())
        encodestrs = base64.b64encode(result)
        enctext = encodestrs.decode('utf8')
        txt(af_filename, enctext)
        time.sleep(1)
        print('... File encrypted successfully ...')
        return enctext
    

    e.发送加密后的文件

    def send_out(af_filename):
        with open(af_filename, 'rb') as file:
            i = file.read()
            amanda.send(i)
        # amanda.send('end'.encode())
        time.sleep(1)  # 推迟执行
        print("... File sent successfully ...")
    

    f.收到加密后的函数后,在服务器解密

    def decrypt(af_filename):
        key = input('Please enter the corresponding key:')
        key = key.encode('utf8')
        text = str(open(af_filename, 'r').read())
        open(af_filename, 'r').close()
        text = base64.b64decode(text)
        cipher = AES.new(key, AES.MODE_ECB)
        msg = cipher.encrypt(pad(text, BLOCK_SIZE))
        decipher = AES.new(key, AES.MODE_ECB)
        msg_dec = decipher.decrypt(msg)
        print("Successfully decrypted, the contents of the file are:")
        print(unpad(msg_dec, BLOCK_SIZE))
    

    解密函数这里卡了不知道有多久,有补码的问题、有忘了转换base64的问题,还有函数参数引用错误的问题、总之对于python实现AES加密解密的知识还不够了解扎实。所以不要急于求成,要基础打好。

    g.上传gitee

    完整代码链接:

    [client.py](client1.py · 2021bestipython/python_20201215 - 码云 - 开源中国 (gitee.com))

    [server.py](server.py · 2021bestipython/python_20201215 - 码云 - 开源中国 (gitee.com))

    运行结果

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

    - 问题1:报错:a bytes-like object is required, not 'str'

    问题出在该语句:

    c.send("欢迎进入聊天系统!")
    

    - 查阅资料发现问题所在:
    原因是 Python3 和 Python2 在套接字返回值解码上有区别
    解决办法:
    1、str 通过 encode() 函数编码为 bytes
    2、bytes 通过 decode() 函数编码为 str。(当我们从网络或磁盘上读取了字节流,则读到的数据就是 bytes)

    - 问题2:报错:bind() takes exactly one argument (2 given)

    - 解决方案:bind()括号中再加一个括号,应该传入元组。用元组表示地址

    - 问题3:不明白实验要求中“监听多个客户请求”的意思

    -解决方案:查阅资料,了解多线编程的概念,学习Python中threading模块

    但是运用还不熟练,于是采取了另一种理解方式,即在客户端加上输入ip地址和端口数字的操作,进行主动连接,这样即可以在多个端口和服务器进行连接。运行结果如下图

    - 问题4:报错:ValueError: Data must be aligned to block boundary in ECB mode

      这个问题卡了好久好久,从网上找了三种方法,应用之后都不能解决。越来越烦躁。最终我决定从头再系统地理解一下AES加密解密方法。在自顶而下地耐心寻找代码错误。

     [Python 实现 AES 加密/解密](Python 实现 AES 加密/解密)

    -问题5:显示无CRYPTO文件

    解决:查阅资料找到以下安装方式

    安装pycrypo

    -问题6:秘钥设置少于16位时报错

    解决办法:加一个if语句判断key的位数,如果不足即补全

    其他(感悟、思考等)

    在了解学习一个新的领域和新知识时,要善于利用网络上存在的作品。一边抄一边学。但也不能只通过这样。应该和完整的基础知识相辅相成。基础知识扎实后才能真正理解代码

    参考资料

    1. str和bytes 的互相转换
    2. [threading](Python多线程编程(一):threading 模块 Thread 类的用法详解_frank 的专栏-CSDN博客_threading)
    3. Python 多线程 | 菜鸟教程 (runoob.com)
    4. 安装pycrypo
    5. Python 实现 AES 加密/解密
  • 相关阅读:
    hdu acm 2844 Coins 解题报告
    hdu 1963 Investment 解题报告
    codeforces 454B. Little Pony and Sort by Shift 解题报告
    广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告
    hdu acm 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
    hdu acm 1114 Piggy-Bank 解题报告
    poj 2531 Network Saboteur 解题报告
    数据库范式
    ngnix 配置CI框架 与 CI的简单使用
    Vundle的安装
  • 原文地址:https://www.cnblogs.com/hahahahahahahaij/p/14819606.html
Copyright © 2011-2022 走看看