python黏包解决方案
解决方案 # 我们可以借助一个模块,这个模块可以把要发送的数据长度转换成固定长度的字节。这样客户端每次接
# 收消息之前只要先接受这个固定长度字节的内容看一看接下来要接收的信息大小,那么最终接受的数据
# 要达到这个值就停止,就能刚好不多不少的接收完整的数据了。 # import json,struct
# #假设通过客户端上传1T:1073741824000的文件a.txt # #为避免粘包,必须自定制报头
# header={'file_size':1073741824000,'file_name':'/a/b/c/d/e/a.txt','md5':'8f6fbf8347faa4924a76856701edb0f3'} #1T数据,文件路径和md5值 # #为了该报头能传送,需要序列化并且转为bytes
# head_bytes=bytes(json.dumps(header),encoding='utf-8') #序列化并转成bytes,用于传输 # #为了让客户端知道报头的长度,用struck将报头长度这个数字转成固定长度:4个字节
# head_len_bytes=struct.pack('i',len(head_bytes)) #这4个字节里只包含了一个数字,该数字是报头的长度 # #客户端开始发送
# conn.send(head_len_bytes) #先发报头的长度,4个bytes
# conn.send(head_bytes) #再发报头的字节格式
# conn.sendall(文件内容) #然后发真实内容的字节格式 # #服务端开始接收
# head_len_bytes=s.recv(4) #先收报头4个bytes,得到报头长度的字节格式
# x=struct.unpack('i',head_len_bytes)[0] #提取报头的长度 # head_bytes=s.recv(x) #按照报头长度x,收取报头的bytes格式
# header=json.loads(json.dumps(header)) #提取报头 # #最后根据报头的内容提取真实的数据,比如
# real_data_len=s.recv(header['file_size'])
# s.recv(real_data_len) # 我们还可以把报头做成字典,字典里包含将要发送的真实数据的详细信息,然后json序列化,
# 然后用struck将序列化后的数据长度打包成4个字节(4个自己足够用了) # 发送时 接收时
# 先发报头的长度 先收报头长度,用struct取出来
# 再编码报头内容然后发送 根据取出的长度收取报头内容,然后解码,反序列化
# 最后发真实内容 从反序列化的结果中取出待取数据的详细信息,然后去取真实的数据内容 #例子:
#server端
import socket, struct, json
import subprocess phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 就是它,在bind前加 phone.bind(('127.0.0.1', 8080)) phone.listen(5) while True:
conn, addr = phone.accept()
while True:
cmd = conn.recv(1024)
if not cmd: break
print('cmd: %s' % cmd) res = subprocess.Popen(cmd.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
err = res.stderr.read()
print(err)
if err:
back_msg = err
else:
back_msg = res.stdout.read() conn.send(struct.pack('i', len(back_msg))) # 先发back_msg的长度
conn.sendall(back_msg) # 在发真实的内容 conn.close() #client端
import socket, struct s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
res = s.connect_ex(('127.0.0.1', 8080)) while True:
msg = input('>>: ').strip()
if len(msg) == 0: continue
if msg == 'quit': break s.send(msg.encode('utf-8')) l = s.recv(4)
x = struct.unpack('i', l)[0]
print(type(x), x)
# print(struct.unpack('I',l))
r_s = 0
data = b''
while r_s < x:
r_d = s.recv(1024)
data += r_d
r_s += len(r_d) print(data.decode('utf-8'))
# print(data.decode('gbk')) #windows默认gbk编码
python黏包解决方案的更多相关文章
- python 缓冲区 subprocess 黏包 黏包解决方案
一.缓冲区 二.两种黏包现象 两种黏包现象: 1 连续的小包可能会被优化算法给组合到一起进行发送 黏包现象1客户端 import socket BUFSIZE = 1024 ip_prort = (' ...
- netty]--最通用TCP黏包解决方案
netty]--最通用TCP黏包解决方案:LengthFieldBasedFrameDecoder和LengthFieldPrepender 2017年02月19日 15:02:11 惜暮 阅读数:1 ...
- python 黏包现象及其解决方案
一.数据缓冲区 缓冲区(buffer),它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的 ...
- python之黏包和黏包解决方案
黏包现象主要发生在TCP连接, 基于TCP的套接字客户端往服务端上传文件,发送时文件内容是按照一段一段的字节流发送的,在接收方看来,根本不知道该文件的字节流从何处开始,在何处结束. 两种黏包现象: 1 ...
- day28 黏包及黏包解决方案
今日主要内容: 一 .缓冲区 二.两种黏包现象 三.黏包现象的两种解决方案 四.打印进度条(补充的,了解即可) 1. 缓冲区 缓冲区的作用 : 将程序和网络解耦(这样做的好处是程序不会以为网速的快慢而 ...
- day 28 黏包及黏包解决方案
1.缓冲区 每个socket被创建以后,都会分配两个缓冲区,输入缓冲区和输出缓冲区,默认大小都是8k,可以通过getsocket()获取,暂时存放传输数据,防止程序在发送的时候卡阻,提高代码运行效率. ...
- Linux tcp黏包解决方案
tcpip协议使用"流式"(套接字)进行数据的传输,就是说它保证数据的可达以及数据抵达的顺序,但并不保证数据是否在你接收的时候就到达,特别是为了提高效率,充分利用带宽,底层会使用缓 ...
- python黏包现象
#黏包:发送端发送数据,接收端不知道应如何去接收造成的一种数据混乱现象. #关于分包和黏包: #黏包:发送端发送两个字符串"hello"和"word",接收方却 ...
- python 黏包现象
一.黏包 1.tcp有黏包现象 表现两种情况 发送的数据过小且下面还有一个发送数据,这两个数据会一起发送 发送的数据过大,超过最大缓存空间,超出的部分在下一次发送的时候发送 原因: tcp是面向流的, ...
随机推荐
- Three学习之曲线
曲线 属性 1. .arcLengthDivisions 当通过.getLengths计算曲线的累积段长度时,此值决定了分割的数量.为了确保在使用.getSpacedPoint等方法时的精度,如果曲线 ...
- (转载)Android常用的Dialog对话框用法
Android常用的Dialog对话框用法 Android的版本有很多通常开发的时候对话框大多数使用自定义或是 Google提供的V4, V7 兼容包来开发保持各个版本的对话框样式统一,所以这里使用的 ...
- ObjecT4:On-line multiple instance learning (MIL)学习
原文链接:http://blog.csdn.net/ikerpeng/article/details/19235391 用到论文,直接看翻译. 文章:Robust object tracking wi ...
- Nginx的安装与升级
1,构建Nginx服务器; 2.升级版本; 一, 构建Nginx服务器 1.使用源码包安装nginx软件包 # yum -y install gcc pcre-devel openssl-devel ...
- 转载:移动端自适应:flexible.js可伸缩布局使用
阿里团队开源的一个库.flexible.js,主要是实现在各种不同的移动端界面实现一稿搞定所有的设备兼容自适应问题. 实现方法: 通过JS来调整html的字体大小,而在页面中的制作稿则统一使用rem这 ...
- 取/etc/password文件最后一个单词的最后一个字符
三种方法都可以 [root@localhost ~]# sed -n "1,5 s#.*\(.\)#\1#p" /etc/passwd [root@localhost ~]# se ...
- JSCH实现文件上传下载至sftp服务器
文件服务器采用FreeSSHd,文件服务器配置就不细说了. 直接上代码,该代码可以直接使用. import com.jcraft.jsch.*; import java.io.InputStream; ...
- node——buffer
buffe方便数据的传输,可一次性传输一部分数据一.类型介绍1.javascript语言没有读取或操作二进制数据的机制.2.Node.js中引入了Buffer类型可以使我们操作TCP流或文件流3.Bu ...
- IOS - xib(Interface Builder,view) - can't change view size(view不能改变大小问题)
很多时候,我们自定义tableview.collectionview的cell,也有时候我们要自定义窗口xib,但创建xib后,其height.width不可修改. 这时问题就来了,怎么才能使我们的自 ...
- [luogu2680] 运输计划 (lca+二分+树上差分)
传送门 Description Input Output 一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间. Sample Input 6 3 1 2 3 1 6 4 3 1 7 4 3 ...