• 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加密与解密

  • 相关阅读:
    Free HTML5 Bootrap Admin Template
    js框架简明
    ELKF(Elasticsearch+Logstash+ Kibana+ Filebeat) 部署
    docker-构建 oracle12c-r2(12.2.0.1) 的镜像
    线上故障排查——drools规则引擎使用不当导致oom
    抓住业务核心,避免过度抽象
    Disruptor的应用示例——大文件拆分
    Disruptor3.0的实现细节
    Disruptor——一种可替代有界队列完成并发线程间数据交换的高性能解决方案
    大文件拆分方案的java实践(附源码)
  • 原文地址:https://www.cnblogs.com/blingblingXY/p/12941904.html
Copyright © 2020-2023  润新知