struct解决socket黏包问题 (指令传输)
服务端代码如下
import struct
import subprocess
import socket
server = socket.socket()
server.bind(('127.0.0.1',))
server.listen()
coon,addr = server.accept()
cmd = coon.recv().decode('utf8')
obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
obj1 = obj.stdout.read()
obj2 = obj.stderr.read()
len_obj = len(obj1+obj2)
len_obj = struct.pack('i',len_obj)
coon.send(len_obj)
coon.send(obj1+obj2)
coon.close()
server.close()
客户端代码
import struct
import socket
client = socket.socket()
client.connect(('127.0.0.1',8900))
cmd = input('>>>')
client.send(cmd.encode('utf8'))
form_server_len = client.recv(4)
print(form_server_len)
form_server_len = struct.unpack('i',form_server_len)[0]
print(form_server_len)
read_len = b''
while len(read_len) < form_server_len:
data = client.recv(1024)
read_len += data
print(read_len.decode('gbk'))
client.close()

每次发送总数据时,要提前将总数据的字节数发过去.
b1 = b'fjdklsfjdsklfjdslfdljskfa' 总长度为:6000个字节 len(b1) = 6000int的字节数
b2 = b'fdisfkljdsjafkl' 总长度为:400个字节 len(b2) = 400 int的字节数
int类型不能直接发送 你要将不同长度的数字类型转化成bytes
6000 ----> str(6000) ----> bytes(6000) b'6000'
此数据的构成: | 数据的总字节数(b'6000')| 具体数据
send(b'6000')
send(b'fjdklsfjdsklfjdslfdljskfa')
由于粘包现象,两次send可能会结合成一个数据发送:
b'6000fjdklsfjdsklfjdslfdljskfa
len(b'6000') 4个字节
recv(4) ---> b'6000'
剩下的6000个字节的数据我要循环recv() b'fjdklsfjdsklfjdslfdljskfa'
你面临的问题: 要将不固定长度的int 转化成固定长度的bytes 利用struct模块
# ret = struct.pack('i',6000)
# print(ret,type(ret),len(ret)) # 固定长度的bytes 4个字节 'b\xe5\x2c\xe1\xe7\'
此数据的构成: | 数据的总字节数(b'6000') (固定长度 4个字节)| 具体数据
send(ret)
send(b'fjdklsfjdsklfjdslfdljskfa')
由于粘包现象,两次send可能会结合成一个数据发送:
b'6000fjdklsfjdsklfjdslfdljskfa
len(b'6000') 4个字节
recv(4) ---> ret 根据struct反解出ret
# w = struct.unpack('i',ret)[0]
# w = 6000 int类型
total_data = b''
while len(total_data) < w:
data = conn.recv(1024)
total_data += data
struct解决socket黏包问题 (指令传输)的更多相关文章
- C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)
介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...
- 解决Socket粘包问题——C#代码
解决Socket粘包问题——C#代码 前天晚上,曾经的一个同事问我socket发送消息如果太频繁接收方就会有消息重叠,因为当时在外面,没有多加思考 第一反应还以为是多线程导致的数据不同步导致的,让他加 ...
- struct 模块解决 TCP黏包问题
首先来看一下产生黏包现象的一段代码: # server.py 服务端 import socket sk = socket.socket() sk.bind(('127.0.0.1',9000)) ...
- 解决socket粘包的两种low版模式 os.popen()和struct模块
os.popen()模式 server端 import socket import os phone = socket.socket() # 实例化一个socket对象 phone.bind((&qu ...
- day 24 socket 黏包
socket 套接字的使用: tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端 server 端 import socket sk = socket.socket() # 实例化一个 ...
- python学习之socket&黏包
7.4 socket [重要] 避免学习各层的接口,以及协议的使用, socket已经封装好了所有的接口,直接使用这些接口或者方法即可,方便快捷,提升开发效率. socket在python中就是一 ...
- 通过大量实战案例分解Netty中是如何解决拆包黏包问题的?
TCP传输协议是基于数据流传输的,而基于流化的数据是没有界限的,当客户端向服务端发送数据时,可能会把一个完整的数据报文拆分成多个小报文进行发送,也可能将多个报文合并成一个大报文进行发送. 在这样的情况 ...
- 网络编程基础【day09】:解决socket粘包之大数据(七)
本节内容 概述 linux下运行效果 sleep解决粘包 服务端插入交互解决粘包问题 一.概述 刚刚我们在window的操作系统上,很完美的解决了,大数据量的数据传输出现的问题,但是在Linux环境下 ...
- Python之黏包的解决
黏包的解决方案 发生黏包主要是因为接收者不知道发送者发送内容的长度,因为tcp协议是根据数据流的,计算机操作系统有缓存机制, 所以当出现连续发送或连续接收的时候,发送的长度和接收的长度不匹配的情况下就 ...
随机推荐
- vue自定义组件添加原生事件监听
注:全局或局部注册的组件称为子组件,其中声明的组件名称(如下demo中的child)是一个自定义组件 Demo1-直接给父组件添加事件监听 <!DOCTYPE html> <html ...
- Dagger2 探索记2——四大基本组件(二)
书接上文,先回顾以下前一章写的内容. 内容大概就是在Activity中用@Inject标记一个注入的类,然后在这个类的构造函数上也打个@Inject标记,然后使用@Component来连接两边,完成对 ...
- 函数体中return下面的代码不执行,但是需要预解析
//函数体中return下面的代码不执行,但是需要预解析 function fn(){ console.log(num);//undefined return function(){ }; var n ...
- getopts举例
- 三、Redis的配置文件和多数据库用途
1.使用文件 # 使用配置文件启动 redis-server ./redis.conf # 带配置文件启动 且指定某几个配置 配置名称前加 -- redis-server ./redis.conf - ...
- 数据库索引原理,及MySQL索引类型(转)
在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable表: CREATE TABLE mytable( ID INT NOT NULL, username ) NOT N ...
- CF963E Circles of Waiting
Circles of Waiting 求一个整点四连通随机游⾛,离原点距离超过R期望步数.R≤50. 带状矩阵法 本质上就是网格图的随机游走. \[ E_x=\sum_y P_{x,y}E_y+1 \ ...
- 最大流的SAP算法模板
明天补充~~~先上代码 #include<iostream> #include<string> #include<queue> #include<vector ...
- WebDriverAgent安装
这次安装WebDriverAgent的过程可谓坎坷呀,最后还是大牛远程解决问题,自己的确差太远,记录一下过程吧 尽量升级Xcode到最新版,保持iPhone的版本大于9.3 终端进入目标文件夹WebD ...
- 【leetcode】922. Sort Array By Parity II
题目如下: 解题思路:非常简单的题目,引入两个变量oddInx = 1和evenInx = 0,和与A等长的结果数组res.然后遍历A,如果A[i]为偶数,则令res[evenInx] = A[i], ...