TCP 粘包及其解决方案(zz)
首先,我们回顾一下 TCP 和 UDP 的头部信息:
具体说明看:http://www.cnblogs.com/aomi/p/7776582.html
我们知道,TCP 和 UDP 是 TCP/IP 协议族传输层中的两个具有代表性的协议。其中,TCP 是面向连接的复杂的、可靠的字节流传输协议,而 UDP 是面向无连接的简单的、不可靠的数据报传输协议。
“流”的概念就是指不间断的数据结构,可以把它想象成你们家里的自来水管道中的水流。什么意思呢?举个例子:TCP 发送端应用程序发送了10次100字节的消息,那么,在接收端的应用程序接收到的可能是一个1000字节的连续不间断的数据。但如果是 UDP 端口发送了一个100字节的消息,那么 UDP 接收端就会以100字节的长度来接收数据。正因为这样,我们可以看到 TCP 头部中并没有长度信息,而 UDP 头部包含长度信息。好了,现在你应该明白我们在创建套接字的时候,为什么 type 的类型是 SOCK_STREAM 和 SOCK_DGRAM 了吧!
正如文章标题所述,显然,你已经知道 UDP 数据包存在明确边界,是不存在粘包现象的,只有 TCP 才会出现粘包现象。那么,接下来我们逐步分析 TCP 的流传输特性所带来如粘包这样的一些问题及其解决方案。
按每次通信后是否闭关连接,可以分为两类情况:长连接和短连接。长连接——指的是客户端和服务端先建立通信连接,连接建立后不断开,然后再进行报文发送和接收。短连接——指的是客户端和服务端每进行一次报文收发交易时才进行通信连接,交易完毕后立即断开连接,比如 http 协议。
所以我们可以分析以下几种情况:
(1)如果利用 TCP 每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题(因为只有一种数据结构)。
(2)如果发送数据无结构,如文件传输,这样发送端只管发送,接收端只管接收存储就行,也不用考虑粘包。
(3)如果双方建立连接,需要在连接后一段时间内发送多个不同结构的数据,这时候接收端收到就可能是一堆粘在一起的数据,这样接收端应用程序就傻了,到底是要干嘛?不知道,因为协议并没有规定这么诡异的数据。
那么,可以认为 TCP 粘包问题并不是对所有应用都造成困扰的,只是对那些长连接并且需要传输多种数据结构的应用造成影响。仔细分析会发现,除了粘包问题,其实还可能会出现多包、少包、半包、断包等情况。
针对这些问题,一般会有如下解决方法:
(1)调用发送函数之后都强制数据立即传送(PUSH 指令)。
(2)对于接收端引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象。
(3)添加一个固定的消息头,该消息头包含数据长度信息,每次数据时先接收固定大小的消息头,再根据其携带的长度信息接收消息实体。也就是说,通过人为控制多次接收来避免粘包。
(4)设置 TCP_NODELAY 选项,禁止 Nagle 算法。
(5)设置 SO_RCVBUF 和 SO_SNDBUF 选项,根据应用需求修改一个合适的接收、发送缓冲区大小。
(6)添加报文分隔标识,比如发送报文是在末尾添加 '\n'
,同时接收端使用 recv() 函数接收报文,并且设置参数 flags 的值为 MSG_PEEK。注意:当 flags 参数的值设置为 MSG_PEEK 时,recv() 可以从 socket 缓存中读取数据,但是不会将缓存中该部分数据清除,但如果使用 read() 函数直接读取 socket 缓存区中的内容,会清空缓存区中的内容。假设两段报文粘包,read() 会清空缓存区中所有内容,从而导致后一段报文中的粘包的部分数据丢失。
实际上,上述的几种解决方法都有不足之处,并且不一定能够完全避免 TCP 粘包问题。所以还是需要根据实际应用来进行应用场景和性能方面的衡量。
参考:
【1】Socket粘包问题
【2】Socket/TCP粘包、多包和少包, 断包
【3】(经典)tcp粘包分析
【4】Linux 网络编程详解五(TCP/IP协议粘包解决方案二)
- 顶
- 1
- 踩
TCP 粘包及其解决方案(zz)的更多相关文章
- python中TCP粘包问题解决方案
TCP协议中的粘包问题 1.粘包现象 基于TCP写一个远程cmd功能 #服务端 import socket import subprocess sever = socket.socket() seve ...
- Netty4实战 - TCP粘包&拆包解决方案
Netty是目前业界最流行的NIO框架之一,它的健壮性.高性能.可定制和可扩展性在同类框架中都是首屈一指.它已经得到了成百上千的商业项目的验证,例如Hadoop的RPC框架Avro就使用了Netty作 ...
- Socket编程(4)TCP粘包问题及解决方案
① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.T ...
- TCP粘包问题及解决方案
① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.T ...
- 【游戏开发】网络编程之浅谈TCP粘包、拆包问题及其解决方案
引子 现如今手游开发中网络编程是必不可少的重要一环,如果使用的是TCP协议的话,那么不可避免的就会遇见TCP粘包和拆包的问题,马三觉得haifeiWu博主的 TCP 粘包问题浅析及其解决方案 这篇博客 ...
- 查漏补缺:socket编程:TCP粘包问题和常用解决方案(上)
1.TCP粘包问题的产生(发送端) 由于TCP协议是基于字节流并且无边界的传输协议,因此很容易产生粘包问题.TCP的粘包可能发生在发送端,也可能发生在接收端.发送端的粘包是TCP协议本身引起的,TCP ...
- 深入了解Netty【八】TCP拆包、粘包和解决方案
1.TCP协议传输过程 TCP协议是面向流的协议,是流式的,没有业务上的分段,只会根据当前套接字缓冲区的情况进行拆包或者粘包: 发送端的字节流都会先传入缓冲区,再通过网络传入到接收端的缓冲区中,最终由 ...
- TCP粘包问题的解决方案01——自定义包体
粘包问题:应用层要发送数据,需要调用write函数将数据发送到套接口发送缓冲区.如果应用层数据大小大于SO_SNDBUF,那么,可能产生这样一种情况,应用层的数据一部分已经被发送了,还有一部分还在 ...
- TCP 粘包 - 拆包问题及解决方案
目录 TCP粘包拆包问题 什么是粘包 - 拆包问题 为什么存在粘包 - 拆包问题 粘包 - 拆包 演示 粘包 - 拆包 解决方案 方式一: 固定缓冲区大小 方式二: 封装请求协议 方式三: 特殊字符结 ...
随机推荐
- mac下使用clion构建boost库
mac下使用clion构建boost库 使用brew install boost 完成后发现boost被安装在在/usr/local/Cellar/boost下 jetbrain给出的指导意见 htt ...
- poi excel导出 xssf 带下拉框
需求:导出之后带有二级级联的下拉框.(类似于省市). 最初的思路是怀疑是不是数组内串太多了,导出之后的excel有36行,调试的误区在于刚开始认为对行数有限制,后自己写了一个测试类,才发现不是行数,而 ...
- HDU 2131 Probability
http://acm.hdu.edu.cn/showproblem.php?pid=2131 Problem Description Mickey is interested in probabili ...
- 大数据Hadoop-1
大数据Hadoop学习之搭建hadoop平台(2.2) 关于大数据,一看就懂,一懂就懵. 一.概述 本文介绍如何搭建hadoop分布式集群环境,前面文章已经介绍了如何搭建hadoop单机环境和伪分 ...
- 【bzoj2438】[中山市选2011]杀人游戏 Tarjan
题目描述 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民 ...
- 洛谷 P1607 [USACO09FEB]庙会班车Fair Shuttle 解题报告
P1607 [USACO09FEB]庙会班车Fair Shuttle 题目描述 Although Farmer John has no problems walking around the fair ...
- 【Cf edu 30 B. Balanced Substring】
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- BZOJ1009: [HNOI2008]GT考试 矩阵快速幂+kmp+dp
这个题你发现打暴力的话可以记忆化搜素加剪枝,那么意味着可以递推,我们搜的话就是1010^9我们就往下匹配遇到匹配成功就return,那么我们可以想一下什么决定了状态,我们考虑kmp的过程,对于我们目前 ...
- Educational Codeforces Round 54 (Rated for Div. 2) ABCD
A. Minimizing the String time limit per test 1 second memory limit per test 256 megabytes Descriptio ...
- poj1185 炮兵阵地 状压dp
司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示) ...