1.粘包概念及产生原因

1.1粘包概念:

  • TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
  • 粘包可能由发送方造成,也可能由接收方造成。
  • 只有TCP有粘包现象,UDP永远不会粘包
  • 粘包不一定会发生

1.2粘包原因:

所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。

  • 发送端原因: 由于TCP协议本身的机制(面向连接的可靠地协议-三次握手机制)客户端与服务器会维持一个连接(Channel),数据在连接不断开的情况下,可以持续不断地将多个数据包发往服务器,但是如果发送的网络数据包太小,那么他本身会启用Nagle算法(可配置是否启用)对较小的数据包进行合并(基于此,TCP的网络延迟要UDP的高些)然后再发送(超时或者包大小足够)。那么这样的话,服务器在接收到消息(数据流)的时候就无法区分哪些数据包是客户端自己分开发送的,这样产生了粘包.
  • 接收端原因: 服务器在接收到数据库后,放到缓冲区中,如果消息没有被及时从缓存区取走,下次在取数据的时候可能就会出现一次取出多个数据包的情况,造成粘包现象。

2. tcp粘包解决办法

  • 在每次使用tcp协议发送数据流时,在开头标记一个数据流长度信息,并固定该报文长度(自定义协议).在客户端接收数据时先接收该长度字节数据,判断客户端发送数据流长度,并只接收该长度字节数据,就可以实现拆包,完美解决tcp粘包问题.
#struct模块介绍
#该模块可以把一个类型,如数字,转成固定长度为4的bytes类型
import struct
res = struct.pack('i',12345) #i表示整数int
print(res,len(res),type(res)) #长度是4 res2 = struct.pack('i',12345111)
print(res,len(res),type(res2)) #长度也是4 unpack_res =struct.unpack('i',res2)
print(unpack_res) #(12345111,)
print(unpack_res[0]) #12345111
###################客户端client###################
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import struct
sock=socket.socket()
sock.connect(('127.0.0.1', 13459)) content1='我好'.encode('utf-8') #要发送消息
content2='他也好'.encode('utf-8') con1_len=struct.pack('i',len(content1)) # 计算要发送消息(字节)的长度,并使用struct模块转化为长度为4的字节b'\x06\x00\x00\x00'
sock.send(con1_len) #先把这个4字节的报文发送
sock.send(content1) #发送内容 con2_len=struct.pack('i',len(content2))
sock.send(con2_len)
sock.send(content2) sock.close()
###################服务端server###################
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import struct
import socket sock = socket.socket() #买手机
sock.bind(('127.0.0.1', 13459)) #插卡
sock.listen(10) #开机(同时最大连接10) conn, addr = sock.accept() #(受)与cilent端connect(攻)对应.
msg = conn.recv(4) #首先接收4个字节(4个字节由client端struct模块转化)
len_msg= struct.unpack('i',msg) #struct模块读取报文,判断跟随数据长度.返回值是一个元祖(6,)
size_msg=len_msg[0] #取值判断跟随数据长度
msg = conn.recv(size_msg) #接收报文读取长度字节
print(msg.decode('utf-8')) #解码输出 msg=conn.recv(4)
len_msg=struct.unpack('i',msg)
size_msg=len_msg[0]
msg = conn.recv(size_msg)
print(msg.decode('utf-8')) conn.close()
sock.close()

!struct模块转化与读取都是对字节进行操作!

tcp粘包问题原因及解决办法的更多相关文章

  1. TCP粘包问题解析与解决

    一.粘包分析 作者本人在写一个FTP项目时,在文件的上传下载模块遇到了粘包问题.在网上找了一些解决办法,感觉对我情况都不好用,因此自己想了个比较好的解决办法,提供参考 1.1 粘包现象 在客户端与服务 ...

  2. TCP粘包,拆包及解决方法

    在进行Java NIO学习时,发现,如果客户端连续不断的向服务端发送数据包时,服务端接收的数据会出现两个数据包粘在一起的情况,这就是TCP协议中经常会遇到的粘包以及拆包的问题.我们都知道TCP属于传输 ...

  3. TCP粘包问题分析和解决(全)

    TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...

  4. 【转载】TCP粘包问题分析和解决(全)

    TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...

  5. 第四章 TCP粘包/拆包问题的解决之道---4.1---

    4.1 TCP粘包/拆包 TCP是一个“流”协议,所谓流,就是没有界限的一串数据.TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可 ...

  6. TCP粘包/拆包问题的解决

    TCP粘包拆包问题 一个完整的包可能被TCP拆分成多个包,或多个小包封装成一个大的数据包发送. 解决策略 消息定长,如果不够,空位补空格 在包尾增加回车换行符进行分割,例如FTP协议 将消息分为消息头 ...

  7. 第四章 TCP粘包/拆包问题的解决之道---4.2--- 未考虑TCP粘包导致功能异常案例

    4.2 未考虑TCP粘包导致功能异常案例 如果代码没有考虑粘包/拆包问题,往往会出现解码错位或者错误,导致程序不能正常工作. 4.2.1 TimeServer 的改造 Class : TimeServ ...

  8. TCP粘包、拆包及解决

    TCP属于传输层的协议,传输层除了有TCP协议外还有UDP协议.那么UDP是否会发生粘包或拆包的现象呢?答案是不会.UDP是基于报文发送的,从UDP的帧结构可以看出,在UDP首部采用了16bit来指示 ...

  9. Android手机出现"已安装了存在签名冲突的同名数据包"的原因及解决办法

    http://blog.csdn.net/dyllove98/article/details/8830264 如果你不是开发者:如果你在android上更新一个已经安装过较早版本软件时,安装到最后一步 ...

随机推荐

  1. [题解]Mail.Ru Cup 2018 Round 1 - B. Appending Mex

    [题目] B. Appending Mex [描述] Ildar定义了一种方法,可以由一个数组产生一个数.具体地,从这个数组中任选一个子集,不在这个子集中的最小的非负整数称为mex,就是由这个数组得到 ...

  2. [题解]hihoCoder挑战赛18——题目1 神奇字符串

    题目地址:http://hihocoder.com/problemset/problem/1264 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 我们说两个字符串是非常 ...

  3. FPGA+x86构建高性能国产网络测试仪竞技之道

    众所周知,以太网已经深入我们的生活无处不在,企业.校园.大数据中心和家庭等都离不开网络,否则我们的生活将受到严重的影响. 以太网的接口速率也是迅速发展:10M.100M.GE.10GE.40GE.10 ...

  4. Mybatis学习笔记(详细)

    介绍 三层架构:视图层.业务逻辑层.持久层 mybatis框架: 执行数据库操作,完成对数据库的增删改查,封装了jdbc mapper映射,将表中数据转为一个Java对象,一个表对应一个接口 Myba ...

  5. Codeforces Round #750 (Div. 2) E. Pchelyonok and Segments

    传送门 题目大意: 给一个序列,可以在这个序列中从左至右选若干个段,第i段的长度为i,对于任意的段i,段内元素和S[i]<S[i+1],求在该序列中最多可以选出几段. 思路:设dp[i][j]为 ...

  6. Go基础知识梳理(三)

    Go基础知识梳理(三) 结构 type Person struct { name string sex int } func main() { //推荐写法 person := Person{ nam ...

  7. gdb调试快速入门

    编译指令 gcc test.c -o test -g -g是加入调试信息,加入源码信息 启动gdb调试 gdb test 进入gdb中 设置参数 set args 10 20 显示参数show age ...

  8. 【一周聚焦】 联邦学习 arxiv 2.16-3.10

    这是一个新开的每周六定期更新栏目,将本周arxiv上新出的联邦学习等感兴趣方向的文章进行总结.与之前精读文章不同,本栏目只会简要总结其研究内容.解决方法与效果.这篇作为栏目首发,可能不止本周内容(毕竟 ...

  9. think php 公共目录common.php json封装

    <?php function getJsonData($code,$massage,$data){ $result=[ 'code'=>$code, 'massage'=>$mass ...

  10. LGP3708题解

    题面很直白,就不说了罢qaq 首先很明显,\(\sum_{i=1}^n x \bmod i = nx - \sum_{i=1}^n i\lfloor \frac x i \rfloor\) 这道题要是 ...