socket编程 粘包和半包 问题的及处理

一般在socket处理大数据量传输的时候会产生粘包和半包问题,有的时候tcp为了提高效率会缓冲N个包后再一起发出去,这个与缓存和网络有关系。

粘包 为x.5个包

半包 为0.5个包

由于网络原因 一次可能会来 0.5/1 /2/ 2.5/ 。。。。个包

当接收到时 要先看看那这个包中有多少个完整的包。把完整的包都处理了 也就是说把x都处理了。剩下的0.5留在接收区中,等待下次接收。

这回接收到的就是0.5+1.5/0.5+1.3/0.5+0.5..... 把完整的包都处理了,有残缺的扔掉 0.8的。

一般情况 接收到正确的后都要给发送端一个应答。不给应答的算超时,发送端将重发。

有头没尾的不能扔

没头有尾的可以扔

有头有尾但缺东西可以扔

有头有尾不缺东西不能扔

之所以出现粘包和半包现象,是因为TCP当中,只有流的概念,没有包的概念.

可以使用UDP协议.这样可以就可以区分每个包了.但是要确保包的丢失处理.为了提到效率,可以考虑写一个滑动窗口进行收发包.

若采用TCP协议进行传输,就要将每个包区分开来.可以有三种方式.因为TCP是面向流的.流只有打开和关闭,你要用一个流传输多个包,那就要向办法区分出每个包.

一:: 可以每次发送同样大小的包,过大的包不予发送,过小的包,后面部分用固定的字符‘\0‘进行填充.

二:: 将流按字符处理,抽出一个字符做转义字符(通常Java用‘\‘来做转义字符,比如"\n"表示换行).假如就设‘\‘为转义字符,发送方如果流当中出现‘\‘,就在后面在追加一个‘\‘,如果包结束,则用‘\‘做包的结束符.这样,在接收方,若读取一个单独的‘\‘或者流结束,就标示前面的内容构成一个包,如果连续读取两个‘\‘,就将两个‘\‘用一个‘\‘进行替换.这样,就可以保证原来包中的信息不变,同时也能区分出每个包了.

三:: 在发送方发送一个包的时候,先将这个包的长度发送给对方(一般是4个字节表示包长),然后再将包的内容发送过去.接收方先接收4个字节,看看包的长度,然后按照长度来接收包,这样就不会出错了. 以上三种方法,是网络传输中经常用到的方法.后两种很常见.最后一种,在TCP长连接传输中应用最多. 综合以上的说法,就是要在TCP协议以上再封装一层协议,用来做分包的信息交换.

一般处理是: 一个BUFFER,用于保存当前连接的读缓存

有数据时,Buffer = Buffer + DataIn,不停的接收

收完成后,开始解析Buffer,

根据包的协议,不停的解析Buffer,并形成一个个包进行处理,处理后,Buffer = Buffer - Data,并继续解包

完成。

原文地址:https://www.cnblogs.com/panchanggui/p/9748204.html

时间: 2024-10-28 22:48:51

socket编程 粘包和半包 问题的及处理的相关文章

SOCKET TCP 粘包及半包问题

大家在使用SOCKET通信编程的时候,一般会采用UDP和TCP两种方式:TCP因为它没有包的概念,它只有流的概念,并且因为发送或接收缓冲区大小的设置问题,会产生粘包及半包的现象. 场景: 服务端向连续发送三个"HelloWorld"(三次消息无间隔),那么客户端接收到的情况会有以下三种: 1)HelloWorld HelloWorld HelloWorld (客户端接收三次) 2)HelloWorldHelloWor ldHelloWorld (客户端接收两次) 3)HelloWorl

C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)

介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解决Socket粘包.半包问题. 更甚至,某些师德有问题的老师,根本就没跟你说过Socket的粘包.半包问题是什么玩意儿. 直到有一天,你的Socket程序在传输信息时出现了你预期之外的结果(多于的信息.不完整的信息.乱码.Bug等等). 任你喊了一万遍“我擦”,依旧是不知道问题出在哪儿! 好了,不说

关于TCP封包、粘包、半包

关于Tcp封包 很多朋友已经对此作了不少研究,也花费不少心血编写了实现代码和blog文档.当然也充斥着一些各式的评论,自己看了一下,总结一些心得. 首先我们学习一下这些朋友的心得,他们是: http://blog.csdn.net/stamhe/article/details/4569530 http://www.cppblog.com/tx7do/archive/2011/05/04/145699.html //……………… 当然还有太多,很多东西粘来粘区也不知道到底是谁的原作,J 看这些朋友

c# socket 解决粘包,半包

处理原理: 半包:即一条消息底层分几次发送,先有个头包读取整条消息的长度,当不满足长度时,将消息临时缓存起来,直到满足长度再解码 粘包:两条完整/不完整消息粘在一起,一般是解码完上一条消息,然后再判断是否有剩余字节,有的话缓存起来,循环半包处理 客户端接收代码: private void callReceived(object sender, SocketAsyncEventArgs args) { var socket = sender as Socket; var bb = args.Use

TCP粘包和半包的处理方法

先把处理的方法的代码放这里: 解析数据帧的代码: bool CSocket::findData(byte* buff, int& len) { for (int i = 0; i <= len - 4; i++) { int dataLen; if(buff[i] == 0xAA && buff[i + 1] == 0xBB) { short slen; slen = (short)(byte(buff[i+3])); slen |=(short)((short)(byte(

【转载】socket的半包,粘包与分包的问题

http://zhaohuiopensource.iteye.com/blog/1541270 首先看两个概念: 短连接: 连接->传输数据->关闭连接    HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接.    也可以这样说:短连接是指SOCKET连接后发送后接收完数据后马上断开连接. 长连接: 连接->传输数据->保持连接 -> 传输数据-> ... ->关闭连接. 长连接指建立SOCKET连接后不管是否使用都

Java 粘包/半包 原理与拆包实战(史上最全)

疯狂创客圈 Java 聊天程序[ 亿级流量]实战系列之13 [博客园 总入口 ] 本文的源码工程:Netty 粘包/半包原理与拆包实战 源码 本实例是<Netty 粘包/半包原理与拆包实战> 一文的源代码工程. 写在前面 大家好,我是作者尼恩. 为了完成了一个高性能的 Java 聊天程序,在前面的文章中,尼恩已经再一次的进行了通讯协议的重新选择. 这就是:放弃了大家非常熟悉的json 格式,选择了性能更佳的 Protobuf协议. 在上一篇文章中,并且完成了Netty 和 Protobuf协议

读懂Java中的Socket编程(转)

Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的.本文会介绍一下基于TCP/IP的Socket编程,并且如何写一个客户端/服务器程序. 餐前甜点 Unix的输入输出(IO)系统遵循Open-Read-Write-Close这样的操作范本.当一个用户进程进行IO操作之前,它需要调用Open来指定并获取待操作文件或设备读取或写入的权限.一旦IO操作对象被打开,那么这个用户进程可以对这个

读懂Java中的Socket编程

Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的.本文会介绍一下基于TCP/IP的Socket编程,并且如何写一个客户端/服务器程序. 餐前甜点 Unix的输入输出(IO)系统遵循Open-Read-Write-Close这样的操作范本.当一个用户进程进行IO操作之前,它需要调用Open来指定并获取待操作文件或设备读取或写入的权限.一旦IO操作对象被打开,那么这个用户进程可以对这个