会员登录|免费注册|忘记密码|管理入口 返回主站||保存桌面|手机浏览|联系方式|购物车
python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验
2024-12-30IP属地 湖北0

黏包现象
让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)
执行远程命令的模块

需要用到模块subprocess

subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。

这就是黏包现象

因为每次执行,固定为1024字节。它只能接收到1024字节,那么超出部分怎么办?
等待下一次执行命令dir时,优先执行上一次,还没有传完的信息。传完之后,再执行dir命令

 总结:

发送过来的一整条信息
由于server端没有及时接受
后来发送的数据和之前没有接收完的数据黏在了一起
这就是著名的黏包现象

问题的根源在于,接收端不知道发送端将要传送的字节流的长度,所以解决粘包的方法就是围绕,如何让发送端在发送数据前,把自己将要发送的字节流总大小让接收端知晓,然后接收端来一个死循环接收完所有数据。

原理:

黏包现象的成因

  你不知道在哪儿断句

解决问题

  在发送数据的时候,先告诉对方要发送的大小就可以了

自定义协议

先和服务端商量好,发送多少字节,再传输数据。

刚刚的方法,问题在于我们我们在发送

通过struck模块将需要发送的内容的长度进行打包,打包成一个4字节长度的数据发送到对端,对端只要取出前4个字节,然后对这四个字节的数据进行解包,拿到你要发送的内容的长度,然后通过这个长度来继续接收我们实际要发送的内容。

这个模块可以把要发送的数据长度转换成固定长度的字节。这样客户端每次接收消息之前只要先接受这个固定长度字节的内容看一看接下来要接收的信息大小,那么最终接受的数据只要达到这个值就停止,就能刚好不多不少的接收完整的数据了。

 

struct模块

该模块可以把一个类型,如数字,转成固定长度的bytes

 

借助struct模块,我们知道长度数字可以被转换成一个标准大小的4字节数字。因此可以利用这个特点来预先发送数据长度。

发送时 接收时

先发报头长度

先收报头长度,用struct取出来 再编码报头内容然后发送 根据取出的长度收取报头内容,然后解码,反序列化 最后发真实内容 从反序列化的结果中取出待取数据的详细信息,然后去取真实的数据内容

 

 

 

 

 

 

 

 

 

 

 

文件的上传和下载

需要文件的名字,文件的大小,文件的内容

自定义一个文件传输协议:

 

注意:

大文件的传输,不能一次性读到内存里

上传一个视频,几台电脑之间能互相传,视频要3个G左右。

进阶需求,加一个登陆功能

1. 引入模块
import hashlib
2. 创建md5对象(实例化)
obj = hashlib.md5(b"盐")
3. 把加密的内容交给md5
obj.update(bytes)
4. 获取密文
obj.hexdigest()

server.py

client.py

 

 先执行server.py,再执行client.py

 

server输出:

('127.0.0.1', 54230)
30e63a254cf081e8e93c036b21057347

 

client输出: