socket编程之黏包
原理概述
上图是我在学习python的socket编程中遇到的黏包问题所画,以实例来说明这个高大上的黏包问题。
我们知道socket()实例中sendall()方法是无论数据有多大,一次性提交写入缓冲区(应用层);再来看接收端,recv()方法有个参数为buffsize,没错buffsize就是套接口的发送缓冲区的大小了。所以数据大于SO_SNDBUF的就会被分块传输,问题就来了,当两次提交的数据都比较大,刚好第一次尾与第二次的首同一时间待在了SO_SNDBUF里,被接收到了,这就是黏包。
一句话:黏包最本质的原因就是接收方不知道接收的包有多大!
解决方法(应用层维护消息和消息边界):
- 定长包
- 包尾加上\r\n标记(FTP)
- 包头增加包体长度。
- 复杂的应用层协议。
实例
本实例多线程实例,实现的是客户端向服务端输入系统命令,服务器返回命令在本机上的执行结果。因为有些命令返回的结果是远大于1024的,所以可能出现黏包的问题。本实例的解决方案是第三条,server端每次向client端返回命令执行结果前,先发送包体大小并得到client端返回的确认信息,再发送数据,程序结构上避免了黏包问题。
TCPSocket服务端
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- import SocketServer
- import os
- class Myserver(SocketServer.BaseRequestHandler):
- def handle(self):
- conn = self.request
- print "Client from:",self.client_address
- conn.sendall("请输入您要查询的命令")
- flag = True
- while flag:
- data = conn.recv(1024)
- print "receive cmd: %s"%data
- if data == "exit":
- flag = False
- else:
- ret = os.popen(data).read().decode("gbk").encode("utf-8")
#发送包大小- conn.sendall(str(len(ret)))
- #收到客户端确认消息。
- scOK = conn.recv(1024)
#发送包体内容- conn.sendall(ret)
- if __name__ == "__main__":
- server = SocketServer.ThreadingTCPServer(("localhost",8000),Myserver)
- server.serve_forever()
TCPSocket客户端
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- import socket
- sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sk.connect(("127.0.0.1",8000))
- sk.settimeout(5)
- data = sk.recv(1024)
- print "SocketServer: %s" % data
- while True:
- reSize = 0
- msg = raw_input("Input:")
- sk.sendall(msg)
#接收包的大小- totleSize = int(sk.recv(1024))
#收到包的大小后,给server端发送确认信息。- sk.sendall("It is ok")
- while True:
- data = sk.recv(1024)
- reSize += len(data)
#当接收数据等于包的size后,跳出循环,停止 接收。- if reSize == totleSize:
- print data
- break
- print data
- if msg == "exit":
- break
- sk.close()
socket编程之黏包的更多相关文章
- python socket编程和黏包问题
一.基于TCP的socket tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端,有顺序,不重复,可靠.不会被加上数据边界. server端 import socket sk = so ...
- Python网络编程基础 ❷ 基于upd的socket服务 TCP黏包现象
TCP的长连接 基于upd的socket服务 TCP黏包现象
- python/socket编程之粘包
python/socket编程之粘包 粘包 只有TCP有粘包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 发送端可以是1k,1k的发送数据而接受端的应用程序可以2k,2k的提 ...
- 2、网络并发编程--套接字编程、黏包问题、struct模块、制作简易报头、上传文件数据
昨日内容回顾 面向对象复习(json序列化类) 对象.类.父类的概念 三大特性:封装 继承 多态 双下开头的方法(达到某个条件自动触发) __init__:对象实例化自动触发 __str__:对象执行 ...
- Python网络编程之黏包问题
二.解决黏包问题 2.1 解决黏包方法1 计算消息实体的大小 服务端接受两次,一次时消息大小,二次是消息实体,解决消息实体黏包 客户端发送两次,一次是消息大小,一次是消息实体 在两次收发之间加入一次多 ...
- Python学习笔记【第十四篇】:Python网络编程二黏包问题、socketserver、验证合法性
TCP/IP网络通讯粘包问题 案例:模拟执行shell命令,服务器返回相应的类容.发送指令的客户端容错率暂无考虑,按照正确的指令发送即可. 服务端代码 # -*- coding: utf- -*- # ...
- 《Python》网络编程之黏包
黏包 一.黏包现象 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. server端 import socket sk = s ...
- socket模块和黏包问题
socket套接字简介 编写cs架构的程序 实现数据交互 OSI七层相当复杂 socket套接字是一门技术 socket模块>>>:提供了快捷方式 不需要自己处理每一层 " ...
- 网络编程- 解决黏包现象方案二之struct模块(七)
上面利用struct模块与方案一比较,减少一次发送和接收请求,因为方案一无法知道client端发送内容的长度到底有多长需要和接收OK.多一次请求防止黏包,减少网络延迟
随机推荐
- spring-mybatis+spring整合
整合之前回忆一下spring和mybatis分别做了什么: spring 通过注解/xml配置,实现AOP和DI DI: 接口实现类中, 将接口私有化,从容器中读取,而不是new一个 UserDao ...
- FFmpeg常用命令学习笔记(七)直播相关命令
直播相关命令 主要涉及到直播中的推流和拉流 1.直播推流 ffmpeg -re -i out.mp4 -c copy -f flv rtmp://server/live/streamName -re: ...
- hbase实践之flush and compaction
本文主要涉及flush流程,探讨flush流程过程中引入的问题并阐述2种解决策略,最后简要说明Flush执行策略. 对于Compaction,本文主要探讨Compaction要解决的本质问题以及由Co ...
- BZOJ 3812 主旋律 (状压DP+容斥) + NOIP模拟赛 巨神兵(obelisk)(状压DP)
这道题跟另一道题很像,先看看那道题吧 巨神兵(obelisk) 题面 欧贝利斯克的巨神兵很喜欢有向图,有一天他找到了一张nnn个点mmm条边的有向图.欧贝利斯克认为一个没有环的有向图是优美的,请问这张 ...
- HDU 6125 - Free from square | 2017 Multi-University Training Contest 7
思路来自这里 - - /* HDU 6125 - Free from square [ 分组,状压,DP ] | 2017 Multi-University Training Contest 7 题意 ...
- SIGAI机器学习第五集 贝叶斯分类器
讲授贝叶斯公式.朴素贝叶斯分类器.正态贝叶斯分类器的原理.实现以及实际应用 大纲: 贝叶斯公式(直接用贝叶斯公式完成分类,计算一个样本的特征向量X属于每个类c的概率,这个计算是通过贝叶斯公式来完成的. ...
- sql server 复习笔记1
查询数据库是否存在: if DB_ID("testDB")is not null; 检查表是否存在: if OBJECT_ID(“textDB”,“U”) is not null ...
- Oracle shell监控小脚本
cat dba_cpu_monitor.sh ##CPU Monitorh=`hostname`cpu_used=`top -b -d 1 -n 2 | grep Cpu | awk 'NR> ...
- STS工具引入jar报问题?(问题待解决)
pom.xml文件中先引入ojdbc6,后修改成ojdbc7了,为啥还报下面的错误: Project 'nx-test-mybatis-oracle' is missing required libr ...
- word如何选择图片粘贴
自动导入Word图片,或者粘贴Word内容时自动上传所有的图片,并且最终保留Word样式,这应该是Web编辑器里面最基本的一个需求功能了.一般情况下我们将Word内容粘贴到Web编辑器(富文本编辑器) ...