20181312 2019-2020-2 《Python程序设计》实验三报告

20181312 2019-2020-2 《Python程序设计》实验三报告

课程:《Python程序设计》
班级:1813
姓名:谢绎
学号:20181312
实验教师:王志强
实验日期:2020年5月16日
必修/选修:公选课

1.实验内容

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

2. 实验过程及结果

socket原理

  • 什么是socket

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

  • 套接字工作流程

    1. 服务器端初始化Socket

    2. 与端口绑定bind

    3. 对端口进行监听listen

    4. 调用accept阻塞

    5. 等待客户端连接


    1. 客户端初始化一个Socket

    2. 连接服务器connect

    3. 如果连接成功,就建立了客户端与服务器端的连接

    4. 客户端发送数据请求,服务器端接收请求并处理请求

    5. 服务器回应数据发送给客户端,客户端读取数据

    6. 关闭连接,一次交互结束

代码设计

  • 客户端(client)

    连接服务器
    import socket
    
    p = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    p.connect(('127.0.0.1', 8080))
    while 1:
        msg = encrypted_text 
        #encrypted_text是经过DES加密后形成的二进制文本
        #DES加密部分见下
        print("从文件" + docu + "中读取到明文")
        print("明文经加密后发送的加密文本是:
    ", msg)
        # 防止输入空消息
        if not msg:
            continue
        p.send(msg)
        break
    p.close()
    
    DES加密部分 && doxc文件读取
    from Cryptodome.Cipher import DES
    from docx import Document
    
    docu = r"C:UsersHPPCdesktop1813明文.docx" #文件储存路径,可以更改
    
    
    def getText(filename):
        #函数将word文档中的文本以字符串形式呈现
        doc = Document(filename)
        fullText = ""
        for para in doc.paragraphs:
            fullText = fullText + para.text + '
    '
        return fullText
    
    
    def pad(text): 
        #由于加密文本text必须为8的倍数,该函数将text补足为8的倍数
        while len(text) % 8 != 0:
            text += ' '
        return text
    
    
    key = b'b4@uF1/='  # 密钥为8位或16位,必须为bytes
    des = DES.new(key, DES.MODE_ECB)  # 创建一个DES实例
    text = getText(docu)
    padded_text = pad(text)
    encrypted_text = des.encrypt(padded_text.encode('utf-8'))  # 加密
    
  • 服务器端(Server)

    套接字函数
    import socket
    
    ip_port = ('127.0.0.1', 8080)
    back_log = 5
    buffer_size = 1024
    #创建一个TCP套接字
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #套接字类型AF_INET, socket.SOCK_STREAM   tcp协议,基于流式的协议
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #对socket的配置重用ip和端口号
    #绑定端口号
    s.bind(ip_port) #写哪个ip就要运行在哪台机器上
    #设置半连接池
    s.listen(back_log) #最多可以连接多少个客户端
    print("服务开启成功")
    while 1:
        #阻塞等待,创建连接
        con, address = s.accept() #在这个位置进行等待,监听端口号
        while 1:
            #DES解密部分见下
    #关闭服务器
    s.close()
    
    DES解密部分 && doxc文件写入
    import socket
    from Cryptodome.Cipher import DES
    from docx import Document
    
    docu = r"C:UsersHPPCdesktop1813解密.docx" #文件储存路径,可以更改
    key = b'b4@uF1/='
    msg = con.recv(buffer_size)
    des = DES.new(key, DES.MODE_ECB)
    plain_text = des.decrypt(msg).decode().rstrip(' ') #解密
    print("解密后的明文时:", plain_text)
    Doc = Document()
    Doc.add_paragraph(plain_text)
    
    Doc.save(docu)
    print("成功保存文件在" + docu)
    break
    

实验结果

首先准备好明文.doxc这个文件,我在这个word里放了一首我喜欢的词《钗头凤·红酥手》

然后运行Server程序,看到服务开启成功字样后,运行Client程序,可以看到

Client界面

Server界面

然后根据文件保存路径,我们打开解密.doxc可以看到

源代码链接

https://gitee.com/python_programming/xieyi_can20181312/tree/master/socket_shiyan

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

  • 问题1:DES加密报错ValueError: Data must be aligned to block boundary in ECB mode

  • 问题1解决方案:增加了pad函数

    def pad(text):
        #由于加密文本text必须为8的倍数,该函数将text补足为8的倍数
        while len(text) % 8 != 0:
            text += ' '
        return text
    

其他(感悟、思考等)

Socket编程的精妙之处远不止表面这些,我最近同时也在学习Java网络编程,发现两者有很多相似之处,python的Socket编程学习使我上手Java网络编程更快一步。

参考资料

Socket编程

Python加密与解密

原文地址:https://www.cnblogs.com/blingblingXY/p/12941904.html