TCP连接,传输数据时的粘包问题讨论
第一个需要讨论的大概就是粘包问题了。因为这个是TCP的个性问题,UDP通信时不存在这个问题的。首先看一下什么叫粘包:
客户端采取与服务器的长连接方式建立通信(Open-Write/Read-Write/Read-……-Write/Read-Close)。即建立连接之后进行多次读写操作,最后才关闭。而且不是文件传输,而是数据结构的传输(文件传输发生粘包与没发生粘包都不会影响结果,反正都是字节流的按顺序写入本地文件)。举个例子来说明一下吧:
两种数据结构:{give me something} {don't give me anything}则粘包是则是接受到{give me something don't give me anything} 这个算是让服务器傻眼了,没见过这么诡异的数据结构,不知道怎么处理了。 |
上面的例子是转的网上的
来分析一下之所以发生粘包的原因吧,其实也就是为什么TCP会发生,但是UDP却不会发生的原因:TCP是面向连接流式无边界的传输方式。当传输通道建立之后,则数据流就像水一样流过来,其中没有数据边界的概念,包随便多大,因而会出现多个包最后粘成一个大包。当然这个是TCP的原因,还有就是缓冲区机制的问题,发送端在默认状况下是需要等到发送去满才发送出去,故而适当使用push刷缓冲区也可减少粘包的现象,还有就是接受缓冲区处理不及时,没有做到来一个包立马处理完这个包。
所以解决的思路大约如下:
- 对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令push,TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满。此种方法关闭了优化算法,降低了网络发送效率,影响应用程序的性能。而且并不能保证100%不发生粘包现象。
- 对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象。该种思路对于接收方的程序算法结构要求较高,而且可靠性不高,因为网络通信中的并发等现象大量存在,很难真的能完全即使处理接受缓冲区而不发生粘包。
- 由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。该思路的问题就更大了,应用程序效率被降低太多。而且我实在不认为这个真能不发生粘包,虽然包变小了,但是并发情况的存在并不能保证接收方有足够的间隙去处理包。
- 预定义数据结构,单线程。字节流前面先加上包头标志位,包头中包含该包的数据长度,这样在读取的时候可按字节读取。这样可有效控制粘包问题。并可以成功避免残包的问题,且不会发生连锁反应,一个坏包的出现不会影响下一个包的正常读取。如{##Length##DataStram}。该中解决方案的优点是可以保证通信的100%准确,缺点是影响程序性能,因为按字节读取包,必定会影响程序的效率。
- 改进:预定义数据结构,单线程。但是不是按字节。查看头标志位,读取包长度,查看缓冲区内包长度,两者相等,则直接读取。如果缓冲区内可读字节数大于标志位描述的包长度,则按照标志位描述的包长度读取数据,如果缓冲区内刻度字节数小于标志位描述的包长度,则线程睡眠,等下一个数据包的到来。
- 预定义数据结构,多线程。服务器端与客户端都是多线程工作,客户端为三个主要线程:发送线程、读取线程与解析线程。服务器端为四个主要线程:监听主线程、接收、读取、解析。按照第五种的思路,拿到数据包之后直接扔给解析线程,解析线程负责数据解析以及最终结果的回调。此处比第五种多的思路就是一个多线程,从而可以很大幅度提升程序的性能。
预定义数据结构示意图:
标志位
长度
数据
参考链接:
http://blog.csdn.net/laoyang360/article/details/8675922
http://www.cnblogs.com/BLoodMaster/archive/2010/07/02/1770067.html
TCP连接,传输数据时的粘包问题讨论的更多相关文章
- C#网络编程学习(5)---Tcp连接中出现的粘包、拆包问题
本文参考于CSDN博客wxy941011 1.疑问 我们使用第四个博客中的项目. 修改客户端为:连接成功后循环向服务器发送从1-100的数字.看看服务器会不会正常的接收100次数据. 可是我们发现服务 ...
- Socket 编程中,TCP 流的结束标志与粘包问题
因为 TCP 本身是无边界的协议,因此它并没有结束标志,也无法分包. socket和文件不一样,从文件中读,读到末尾就到达流的结尾了,所以会返回-1或null,循环结束,但是socket是连接两个主机 ...
- UNIX网络编程——tcp流协议产生的粘包问题和解决方案
我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体 ...
- tcp流协议产生的粘包问题和解决方案
我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体 ...
- python 之网络编程(基于TCP协议Socket通信的粘包问题及解决)
8.4 粘包问题 粘包问题发生的原因: 1.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包),这样接收端,就难于分辨出来了,必须提供科学的拆包机制. ...
- Go语言网络通信---tcp上传大文件(粘包问题还需优雅解决)
server端: package main import ( "bufio" "encoding/binary" "fmt" "n ...
- tcp协议传输中的粘包问题
什么是粘包问题 tcp是流体协议. 其nagle算法会将数据量较小. 并且发送间隔时间较短的多个数据包合并为一个发送. 网络传输的时候是一段一段字节流的发送. 在接收方看来根本不知道字节流从何开始. ...
- TCP 远程执行CMD (解决粘包问题) 代码
服务端 from socket import * import subprocess,json,struct server= socket(AF_INET,SOCK_STREAM) server.bi ...
- TCP粘包问题
1.什么是粘包? 粘包指的是数据与数据之间没有明确的分界线,导致不能正确的读取数据.换句话说就是接收方不知道发送方一次到底发送了多少数据.只有TCP才会出现粘包现象,UDP不会出现粘包现象,因为TCP ...
随机推荐
- Android 高级UI设计笔记12:ImageSwitcher图片切换器
1. ImageSwitcher ImageSwitcher是Android中控制图片展示效果的一个控件,如:幻灯片效果...,颇有感觉啊.做相册一绝 2. 重要方法 setImageURI(Uri ...
- 如何解决sql server 2008附加数据库失败
MDF文件是数据库存贮数据的文件,可以通过附加的方法添加到数据库,在添加mdf文件的时候遇到附加数据库失败,具体提示如下: microsoft SQL server,错误5120 最初以为是附加权限的 ...
- GetImage
check路径是是否有效,网络访问地址.notfound查找不到,httpstatuscode枚举数较多,根据自己想要的设置就好了. public bool checkValid(string pat ...
- SlickOne -- 基于Dapper, Mvc和WebAPI 的快速开发框架
前言:在两年前,项目组推出了基于Dapper,Mvc和WebApi的快速开发框架,随着后续Slickflow产品的实践和应用,今再次对SlickOne项目做以回顾和总结.其目的是精简,持续改进,保持重 ...
- JS 操作JSON字符串
用Js的eval解析JSON中的注意点 在JS中将JSON的字符串解析成JSON数据格式,一般有两种方式: 1.一种为使用eval()函数. 2. 使用Function对象来进行返回解析. 使用eva ...
- PHP浮点数的精度
在百度知道上看到这么一个问题 var_dump((0.3-0.2)==0.1); 结果是:false 后来查查手册,原来是浮点数的精度问题.那么0.3-0.2-0.1等于多少呢,结果:2.775557 ...
- View的setOnClickListener的添加方法
1)第一种,也是最长见的添加方法(一下都以Button为例) 1 Button btn = (Button) findViewById(R.id.myButton);2 btn .setOnClick ...
- 根据数据库内容动态生成html页面
之前使用了很多方法,但是都很复杂. 项目里包括了数据库的管理页面,对数据库进行修改(新增,插入,删除)等之后,在另一个页面使用. 使用时采用按下相应label弹出所有信息的方法,以html的形式将数据 ...
- 如何下载免费英特尔® 实感™ SDK
英特尔® 实感™ SDK支持的用途包括手/指跟踪.面部分析.语音识别和合成.背景分段.增强现实性等等,给你带来全新的人机交互体验.还不赶紧跟着我们一起免费下载英特尔® 实感™ SDK吧! 1. 输入网 ...
- MPlayerX For Mac白屏问题
在Mac App store下载了MPlayerX后,如果系统版本是10.10的,用MPlayerX看视屏当选择全屏后会出现白屏现象只有声音退出全屏后仍旧是白屏. 这是因为MPlayerX已经在Mac ...