zoukankan      html  css  js  c++  java
  • 20183122 实验三《Python程序设计》实验报告

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

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

    1.实验内容

    1)、创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
    2)、实现客户端和服务器端的文件(支持任意类型的文件,如txt、mp4、jpg、png、html等)发送和接收,发送的数据采用DES加密。

    2. 实验过程及结果

    1)、搭建大致框架,在客户端与服务器端建立连接,服务器端实现一直工作,不受客户端异常退出导致传输异常的影响。

    2)、在发送端进行数据的处理。

    a、构造报头,包括要发送的文件名,操作的文件大小等信息;
    cmd = input("请输入命令:")
    if cmd == "exit":
        exit(0)
    try:
        action, filename = cmd.strip().split(' ')
        filesize = os.path.getsize(filename)
    except:
        print("命令错误或找不到文件")
        break
    
    b、先利用json模块将报头字典转化成比特流,再利用struct模块封包报头比特流长度,使其长度固定为4字节;
    file_info_bytes = json.dumps(file_info).encode()
    len_header = len(file_info_bytes)
    res = struct.pack("i", len_header)
    
    c、完成上述步骤后就可以发送数据了:以二进制只读的方式打开文件,逐行加密并发送,再利用md5.updata()方法更新摘要值;
    d、发送完成后等待接收端校验并发回反馈

    3)、在接收端进行数据的处理。

    a、接收4比特的报头部分长度的封包;
    b、对前一步获得的数据进行解包,得到比特流长度,再根据长度接收报头,利用json模块将其还原成字典,得到完整的报头;
    res = struct.unpack("i", len_header)
    ···
    header = json.loads(info_header)
    
    c、接收数据并对数据进行校验,将校验的结果发送给发送方;
    recv_md5: str = conn.recv(1024).decode()
    if md5.hexdigest() == recv_md5:
        print("文件完整性验证通过")
        print('*' * 50)
        conn.send("文件完整性验证通过".encode())
    else:
        print("文件完整性验证失败,发送过程中文件可能丢失或被篡改!!!")
        print('*'*50)
        conn.send("文件完整性验证失败,发送过程中文件可能丢失或被篡改!!!".encode())
    

    运行结果:

    运行前:(可以看到,运行前服务器端对应的文件夹中没有文件):

    服务器端运行中(可以看到即使客户端异常退出服务器端也能继续运行):

    客户端运行结果:

    运行后,服务器端的文件夹中多了相应的内容:

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

    问题1:自己写的加密解密模块导入失败

    问题1解决方案:将自己的模块所在的文件夹设定为Source root型
    

    问题2:黏包:连续send时接收端分不清边界

    问题2解决方案:
      发送端:
            先发送报头长度
            再编码报头内容并发送
            最后发送数据
      接收端:
            接受报头长度
            按照接收的长度接收报头并解包
            最后接收数据
    

    其他

    服务器端:https://gitee.com/konelee/python_programming/blob/master/实验三服务器端.py
    客户端:https://gitee.com/konelee/python_programming/blob/master/实验三客户端.py
    在实验初期我并不知道会存在黏包的现象,因为当时我传送的都是比较小的文件,接收端一次就可以完全接收,后来我用较大的mp4文件做实验,发现接收端在recv()处阻塞了,但此时它本应收到来自发送端的验证文件完整性的摘要的,查找资料之后我才得知出现此现象是由于黏包。刚开始研究黏包现象的时候,我发现time.sleep()可以解决黏包问题,但这种方式实在太low,极其浪费资源和时间,使传输效率大打折扣;于是我寻找到了利用构造报头来实现的解决黏包,这种方式解决黏包问题十分高效,对传输效率基本没有影响。

  • 相关阅读:
    第四章 连接管理
    第三章 http报文
    第二章 URL与资源
    第一章 http概述
    html5 canvas 游戏地图绘制
    jqGrid 编辑完数据后能返回到当前位置的方法
    发布APP到app store
    STSDB、NDataBase 对象数据库在不同.net framework下无法读取的解决办法
    System.Json 使用注意
    TiQuery
  • 原文地址:https://www.cnblogs.com/konelee/p/12923289.html
Copyright © 2011-2022 走看看