python_网络编程struct模块解决黏包问题
为什么会出现黏包现象:
首先只有在TCP协议中才会出现黏包现象,是因为TCP协议是面向流的协议,在发送的数据传输的过程中还有缓存机制来避免数据丢失,因此,在连续发送小数据的时候,以及接收大小不符的时候容易出现黏包现象。本质还是因为我们在接收数据的时候不知道发送的数据的长短。
解决黏包问题
在传输大量数据之前首先告诉接收端要发送的数据大小,如果想更漂亮的解决问题,可以通过struct模块来定制协议。
struct模块:
功能:可以把一个类型,如数字,转成固定长度的bytes。
import struct
ret = struct.pack('i',456872783) #'i'代表int,就是即将要把一共数字转换成固定长度(4个字节)的bystes类型
print(ret)
num = struct.unpack('i',ret) #转换回来,返回一个元组
print(num[0]) #提前元组中的值得到4096
解决黏包问题:
服务端:
import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
conn,addr = sk.accept()
while True:
cmd = input('>>>')
if cmd == 'q': #当输入‘q’时,结束,并向客户端发送一个'q'。
conn.send(b'q')
break
conn.send(cmd.encode('gbk')) #将输入的cmd命令发送给客户端
num = conn.recv(4) #接收字节信息(返回的消息长度信息)。
num = struct.unpack('i',num)[0] #将接收的字节码转化为原来的类型并放在一个元组里面,后面加[0]是提前出元组中的值。
res = conn.recv(int(num)).decode('gbk') #接收长度为num 的消息。
print(res) #打印
conn.close()
sk.close()
客户端:
import struct
import socket
import subprocess sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
cmd = sk.recv(1024).decode('gbk') #接收服务端发送来的cmd命令
if cmd == 'q': #当接收到‘q’时,结束。
break
# 在客户端执行接收到的cmd命令。并将正确的消息和错误的消息分别放入stdout和stderr管道。
res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
std_out = res.stdout.read() #读取管道内正确的消息
std_err = res.stderr.read() #读取管道内错误的消息
len_num = len(std_out)+len(std_err) #计算正确和错误消息的总长度
num_by = struct.pack('i',len_num) #将消息总长度转换成长度为4的字节码
sk.send(num_by) #发送消息长度信息
sk.send(std_out) #发送正确消息
sk.send(std_err) #发送错误消息 sk.close()
python_网络编程struct模块解决黏包问题的更多相关文章
- Python网络编程基础 struct模块 解决黏包问题 FTP
struct模块 解决黏包问题 FTP
- day29-struct模块解决黏包问题
#struct模块可以把一个数据类型,例如数字int,转化成固定长度(4个字节)的bytes.int转为4个bytes. #在大量传输数据之前先告诉接收端即将接收数据的大小,方可解决黏包问题: #利用 ...
- python_网络编程hmac模块验证客户端的合法性
hmac模块: 比较两个函数的密钥是否一致: import hmac import os msg = os.urandom(32) #生成32位随机字节码 def wdc(): key = b'wdc ...
- python_网络编程socketserver模块实现多用户通信
服务端: import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): #在这个函数里面 ...
- python网络编程基础之socket粘包现象
粘包现象两种 登陆 #服务端import json import socket server=socket.socket()#创建socket对象 ip_port=('127.0.0.1',8001) ...
- python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验
一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess sub ...
- struct 模块解决 TCP黏包问题
首先来看一下产生黏包现象的一段代码: # server.py 服务端 import socket sk = socket.socket() sk.bind(('127.0.0.1',9000)) ...
- python 网络编程--socket模块/struct模块
socket模块: 客户端:CS架构, client -> server 浏览器:BS架构, browser -> server 网络通信本质:传输字节 doc命令查看ip地址:ipc ...
- 31_网络编程-struct
一.struct 1.简述 我们可以借助一个模块,这个模块可以把要发送的数据长度转换成固定长度的字节.这样客户端每次接收消息之前只要先接受这个固定长度字节的内容看一看接下来要接收的信息大小,那么 ...
随机推荐
- 乐字节Java反射之四:反射相关操作
大家好,乐字节小乐继续为Java初学者讲述Java基础知识.上次说到乐字节Java反射之三:方法.数组.类加载器,这次是Java反射之四:反射相关操作 1.操作属性 //1.获取Class对象 Cla ...
- 什么是H5?
总听到很多人说H5,现在H5很火,到底H5是什么,以下发表个人对H5的理解. HTML5 将成为 HTML.XHTML 以及 HTML DOM 的新标准. HTML 的上一个版本诞生于 1999 年. ...
- Redis 集群_主从复制_哨兵模型
1 redis集群简介 1.1 集群的概念 所谓的集群,就是通过添加服务器的数量,提供相同的服务,从而让服务器达到一个稳定.高效的状态. 1.1.1 使用redis集群的必要性 问题:我们已经部署好了 ...
- db2 数据库配置HADR+TSA添加集群节点
Db2配置HADR高可用+TSA添加集群节点 一.服务器资源 Master IP:10.78.10.1 数据库:dbclassSlave IP:10.78.10.2 数据库:dbclassVIP:10 ...
- c# 面向对象/继承关系设计
继承 RTTI RTTI 概念 RTTI(Run Time Type Identification)即通过运行时类型识别,程序能够使用基类的指针或引用来检查着这些指针或引用所指的对象的实际派生类型. ...
- Java操作word转pdf
如果转换后出现乱码,是doc格式的文档的话请转换为docx!!! 下载相关jar包和一个授权到2099年的凭证文件. 链接: https://pan.baidu.com/s/1xudkKqR1-TLL ...
- STM32启动文件详解
启动文件使用的 ARM 汇编指令汇总 启动程序源码注释(点此下载) 1. Stack—栈 Stack_Size EQU 0x00000400 AREA STACK, NOINIT, READWRITE ...
- 【判环】Perpetuum Mobile
Perpetuum Mobile 题目描述 The year is 1902. Albert Einstein is working in the patent office in Bern. Many ...
- 前端 aes 加密
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- AtCoder Grand Contest 040 B - Two Contests
传送门 一看就感觉很贪心 考虑左端点最右的区间 $p$ 和右端点最左的区间 $q$ 如果 $p,q$ 属于同一个集合(设为 $S$,另一个集合设为 $T$),那么其他的区间不管是不是在 $S$ 都不会 ...