为什么会出现黏包现象:

  首先只有在TCP协议中才会出现黏包现象,是因为TCP协议是面向流的协议,在发送的数据传输的过程中还有缓存机制来避免数据丢失,因此,在连续发送小数据的时候,以及接收大小不符的时候容易出现黏包现象。本质还是因为我们在接收数据的时候不知道发送的数据的长短。

解决黏包问题

  在传输大量数据之前首先告诉接收端要发送的数据大小,如果想更漂亮的解决问题,可以通过struct模块来定制协议。

struct模块:

  功能:可以把一个类型,如数字,转成固定长度的bytes。

  1. import struct
  2.  
  3. ret = struct.pack('i',456872783) #'i'代表int,就是即将要把一共数字转换成固定长度(4个字节)的bystes类型
  4. print(ret)
  5.  
  6. num = struct.unpack('i',ret) #转换回来,返回一个元组
  7. print(num[0]) #提前元组中的值得到4096

解决黏包问题:

  服务端:

  1. import struct
  2. import socket
  3. sk = socket.socket()
  4. sk.bind(('127.0.0.1',8080))
  5. sk.listen()
  6. conn,addr = sk.accept()
  7. while True:
  8. cmd = input('>>>')
  9. if cmd == 'q': #当输入‘q’时,结束,并向客户端发送一个'q'。
  10. conn.send(b'q')
  11. break
  12. conn.send(cmd.encode('gbk')) #将输入的cmd命令发送给客户端
  13. num = conn.recv(4) #接收字节信息(返回的消息长度信息)。
  14. num = struct.unpack('i',num)[0] #将接收的字节码转化为原来的类型并放在一个元组里面,后面加[0]是提前出元组中的值。
  15. res = conn.recv(int(num)).decode('gbk') #接收长度为num 的消息。
  16. print(res) #打印
  17. conn.close()
  18. sk.close()

  客户端:

  1. import struct
  2. import socket
  3. import subprocess
  4.  
  5. sk = socket.socket()
  6. sk.connect(('127.0.0.1',8080))
  7. while True:
  8. cmd = sk.recv(1024).decode('gbk') #接收服务端发送来的cmd命令
  9. if cmd == 'q': #当接收到‘q’时,结束。
  10. break
  11. # 在客户端执行接收到的cmd命令。并将正确的消息和错误的消息分别放入stdout和stderr管道。
  12. res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
  13. std_out = res.stdout.read() #读取管道内正确的消息
  14. std_err = res.stderr.read() #读取管道内错误的消息
  15. len_num = len(std_out)+len(std_err) #计算正确和错误消息的总长度
  16. num_by = struct.pack('i',len_num) #将消息总长度转换成长度为4的字节码
  17. sk.send(num_by) #发送消息长度信息
  18. sk.send(std_out) #发送正确消息
  19. sk.send(std_err) #发送错误消息
  20.  
  21. sk.close()

python_网络编程struct模块解决黏包问题的更多相关文章

  1. Python网络编程基础 struct模块 解决黏包问题 FTP

    struct模块 解决黏包问题 FTP

  2. day29-struct模块解决黏包问题

    #struct模块可以把一个数据类型,例如数字int,转化成固定长度(4个字节)的bytes.int转为4个bytes. #在大量传输数据之前先告诉接收端即将接收数据的大小,方可解决黏包问题: #利用 ...

  3. python_网络编程hmac模块验证客户端的合法性

    hmac模块: 比较两个函数的密钥是否一致: import hmac import os msg = os.urandom(32) #生成32位随机字节码 def wdc(): key = b'wdc ...

  4. python_网络编程socketserver模块实现多用户通信

    服务端: import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): #在这个函数里面 ...

  5. python网络编程基础之socket粘包现象

    粘包现象两种 登陆 #服务端import json import socket server=socket.socket()#创建socket对象 ip_port=('127.0.0.1',8001) ...

  6. python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验

    一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess sub ...

  7. struct 模块解决 TCP黏包问题

    首先来看一下产生黏包现象的一段代码: # server.py 服务端 import socket ​ sk = socket.socket() sk.bind(('127.0.0.1',9000)) ...

  8. python 网络编程--socket模块/struct模块

    socket模块: 客户端:CS架构,  client -> server 浏览器:BS架构,  browser -> server 网络通信本质:传输字节 doc命令查看ip地址:ipc ...

  9. 31_网络编程-struct

    一.struct   1.简述  我们可以借助一个模块,这个模块可以把要发送的数据长度转换成固定长度的字节.这样客户端每次接收消息之前只要先接受这个固定长度字节的内容看一看接下来要接收的信息大小,那么 ...

随机推荐

  1. 《ucore lab1 exercise3》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 题目:分析bootloader进入保护模式的过程 BIOS将通过读取硬盘主引导扇区到内存,并转跳到对应内存中的位置执行bootloader.请分 ...

  2. 【转帖】一文看懂docker容器技术架构及其中的各个模块

    一文看懂docker容器技术架构及其中的各个模块 原创 波波说运维 2019-09-29 00:01:00 https://www.toutiao.com/a6740234030798602763/ ...

  3. logback的xml配置文件模板(超详细)

    <?xml version="1.0" encoding="UTF-8" ?> <!-- 在此未说明属性为非必须的,那就表示属性必须设置 -- ...

  4. Java语言资源国际化步骤

    语言资源国际化步骤:   1. 定义资源文件(如:language),需要使用命令native2ascii命令进行转码:(native2ascii是jdk中的转码工具,在jdk的bin目录下)   2 ...

  5. 创客课堂——Scratch实例演示

    大家好,这里是蓝精灵创客公益课堂,我是蓝老师. 前两期我们认识了Scratch的界面和菜单功能,本期我们就可以根据提示的步骤,学习一些Scratch的基本操作. 下面就开始今天学习内容 一.开始移动 ...

  6. 写文章 通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!

    网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底 ...

  7. row_number() over()函数基本用法

    简单的说row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY xlh DESC) 是先把xlh列降序,再为降序以后的没条xlh记 ...

  8. pytorch自定义网络层以及损失函数

    转自:https://blog.csdn.net/dss_dssssd/article/details/82977170 https://blog.csdn.net/dss_dssssd/articl ...

  9. 【shell脚本】$ 在shell脚本中的使用

    shell脚本中 '$' 与不同的符号搭配其表示的意义也会不同 特殊标志符 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数.n 是一个数字,表示第几个参数. 例如,第一个参数是$1,第二个 ...

  10. [Vuex系列] - Actions的理解之我见

    Actions如何定义的 恕小端不才,对Action的总结如下: Action 可以提交mutation方法,通过mutation来改变state Action 函数可以接收一个context对象,通 ...