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 加密/解密
  • 相关阅读:
    基于Token的身份验证--JWT
    在eclipse中使用maven创建springMVC项目
    Mybatis框架插件PageHelper的使用
    java 中==符号的坑
    Gradle project sync failed.
    intellij idea android错误: Missing styles. Is the correct theme chosen for this layout?
    thinkpad win8.1 无线连接受限
    struts2
    在Strust2 使用datatimepicker 标签引发的一系列问题
    struts2中css,js等资源无效 非路径问题(新手问题)
  • 原文地址:https://www.cnblogs.com/hahahahahahahaij/p/14819606.html
Copyright © 2011-2022 走看看