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

panchanggui panchanggui     2023-01-05     639

关键词:

一般在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是面向流的.流只有打开和关闭,你要用一个流传输多个包,那就要向办法区分出每个包.

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

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

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

 

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

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

收完成后,开始解析Buffer,

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

完成。

 

粘包和半包有了解过吗?netty是如何解决这个问题的(代码片段)

...列文章,学习或面试都可以看看(一)什么是粘包、半包在实际的网络开发中或者在面试中,最开始使用TCP协议时经常会碰上粘包和半包的情况,因此我们有必要了解一下什么是粘包,什么是半包,以... 查看详情

tcp粘包与半包的核心

  进行Socket编程时经常会碰到 TCP的粘包与半包问题,很多时候我们选用netty等框架而不直接采用原生的Socket编程也是因为netty帮我们将该类传输过程中可能出现的问题屏蔽掉了,使我们可以抽出更多精力来关注功能的实现... 查看详情

socket解决半包粘包问题(代码片段)

 最近项目遇到socket服务端接收报文不全的问题,与其客户端约定的是报文长度+报文体。然而当客户端数据量大的时候,用分包发送,导致服务端报文日志接收不完整,于是想着先读出包体长度,再读出包体,不够就一直读... 查看详情

netty进阶——粘包与半包(代码示例)(代码片段)

目录一、消息粘包和消息半包的概述1.1、消息粘包1.2、消息半包二、粘包现象代码示例2.1、粘包现象服务端示例代码2.2、粘包现象客户端示例代码2.3、分别启动服务端,客户端,查看服务端结果输出三、半包现象代码示... 查看详情

javasocket编程解决粘包和丢包问题

##socket丢包粘包解决方式采用固定头部长度(一般为4个字节),包头保存的是包体的长度header+body包头+包体 思路是:先读出一个包头,得到包体的长度,解析出包体 publicclassSocketServer{publicstaticvoidmain(Stringargs[]){ServerSockets... 查看详情

详解啥是tcp粘包和拆包现象并演示netty是如何解决的

...后再通过一个Netty的demo来解决这个问题。具体内容如下TCP编程底层都有粘包和拆包机制,因为我们在C/S这种传输模型下,以TCP协议传输的时候,在网络中的byte其实就像是河水,TCP就像一个搬运工,将这流水从一端转送到另一端,... 查看详情

粘包和拆包(代码片段)

写在前面粘包、拆包是Socket编程中最常遇见的一个问题,本文只对粘包、拆包现象及发生的原因做简要分析,具体如何解决粘包和拆包的问题,在后续文章中会详细介绍。什么是粘包、拆包TCP是个"流"协议,所谓流,就是没有界... 查看详情

socket编程[oc](逻辑数据的处理)(代码片段)

 之前写了一下socket编程中半包、粘包的处理点击打开链接,这篇再写写另一个相关问题,逻辑数据的处理物理数据包与逻辑数据包: 首先说明的是,socket传输中物理数据包、逻辑数据包的概念是我自己臆想、“定义... 查看详情

mina中的tcp粘包,半包的问题

...发两端(客户端和服务器端)都要有一一成对的socket,因 此,发送端为了将多个发往接收端的包,更有效 查看详情

网络编程(socket)中的粘包处理

服务端  importsocket,osservice=socket.socket()service.bind((‘localhost‘,1024))#绑定要监听的端口service.listen()###监听端口con,adder=service.accept()#等对方的连接,把对方的连接在本地生成一个实例并赋值个给conwhileTrue:data=con.recv(1024).decode 查看详情

day8---多线程socket编程,tcp粘包处理

复习下socket编程的步骤:服务端: 1声明socket实例server=socket.socket() #括号里不写 默认地址簇使用AF_INET 即IPv4   默认type为sock.SOCK_STREAM即TCP/IP协议  2绑定IP地址和端口server.bind((‘localhost‘,99 查看详情

day08多线程socket编程,tcp粘包处理

 服务端: 1声明socket实例server=socket.socket() #括号里不写 默认地址簇使用AF_INET 即IPv4   默认type为sock.SOCK_STREAM即TCP/IP协议  2绑定IP地址和端口server.bind((‘localhost‘,9999))  查看详情

服务端netty客户端非netty处理粘包和拆包的问题

之前为了调式和方便一直没有处理粘包的问题,今天专门花了时间来搞NETTY的粘包处理,要知道在高并发下,不处理粘包是不可能的,数据流的混乱会造成业务的崩溃什么的我就不说了。所以这个问题在我心里一直是个结。 ... 查看详情

netty进阶——粘包与半包(短链接方式解决粘包问题)(代码片段)

目录一、短链接方式解决粘包问题(代码示例)1.1、短链接方式解决粘包问题的服务端代码示例1.2、短链接方式解决粘包问题的客户端代码示例1.3、分别启动服务端,客户端,查看服务端结果输出一、短链接方式... 查看详情

netty进阶——粘包与半包(短链接方式解决粘包问题)(代码片段)

目录一、短链接方式解决粘包问题(代码示例)1.1、短链接方式解决粘包问题的服务端代码示例1.2、短链接方式解决粘包问题的客户端代码示例1.3、分别启动服务端,客户端,查看服务端结果输出一、短链接方式... 查看详情

netty进阶——粘包与半包(固定长度方式解决粘包问题)(代码片段)

目录一、固定长度方式解决粘包问题(代码示例)1.1、固定长度方式解决粘包问题的服务端代码示例1.2、固定长度方式解决粘包问题的客户端代码示例1.3、分别启动服务端,客户端,查看服务端结果输出一、固定... 查看详情

netty进阶——粘包与半包(固定长度方式解决粘包问题)(代码片段)

目录一、固定长度方式解决粘包问题(代码示例)1.1、固定长度方式解决粘包问题的服务端代码示例1.2、固定长度方式解决粘包问题的客户端代码示例1.3、分别启动服务端,客户端,查看服务端结果输出一、固定... 查看详情

netty进阶——粘包与半包(预设长度方式解决粘包问题)(代码片段)

目录一、预设长度方式解决粘包问题(代码示例)1.1、预设长度方式解决粘包问题的服务端代码示例1.2、预设长度方式解决粘包问题的客户端代码示例1.3、分别启动服务端,客户端,查看服务端结果输出一、预设... 查看详情