美文网首页
Socket粘包,拆包处理

Socket粘包,拆包处理

作者: 柠檬君Air | 来源:发表于2022-03-11 08:29 被阅读0次

在iOS中用socket做即时通讯时,经常会遇到粘包的问题。

什么是粘包?

粘包:socket传输数据是由多个连续的数据包组成,他们被连续的存储在缓存中,在读取数据包时可能由于某些原因导致获取到了错误的发送边界,这时后就会出现后一个数据包的头连接在了前一个数据包的尾部。

怎么解决粘包?

因为TCP协议是基于字节流的,所以在应用层就要自己解决数据的边界问题。
一般来说,定义数据有两种方式,定义长度 或者 定义一个终结符。
下面通过项目中的代码来解释怎么解决粘包。

func didReadData(_ data:Data){
        //接收的数据先写入缓存
        cache += [UInt8](data)
        while cache.count>8 {
            print("读取到数据,开始解析,剩余数据长度:\(cache.count)")
            //0-4位存储消息类型
            let typeBytes = cache[0..<4]
            //4-8位存储数据包长度
            let lengthBytes = cache[4..<8]
            let typeData = Data(typeBytes)
            let lengthData = Data(lengthBytes)
            //注意大小端转换问题
            let type = Int32(bigEndian: typeData.withUnsafeBytes { $0.baseAddress!.bindMemory(to: Int32.self, capacity: 4).pointee })
            let length = Int32(bigEndian: lengthData.withUnsafeBytes { $0.baseAddress!.bindMemory(to: Int32.self, capacity: 4).pointee })
            //数据包长度不够,跳出循环,继续读取笑一个包
            if cache.count < 8+Int(length){
                break
            }
            //获取到完整的数据包
            let resultBytes = cache[8..<8+Int(length)]
            let resultData = Data(resultBytes)
            //将数据传给delegate进行处理
            self.delegate?.socketDidRead(type: type, data: resultData,retry:true)
            //沾包循环读取
            let begin = 8+Int(length)
            let end = cache.count
            cache = Array(cache[begin..<end])
        }
        sendSocket?.readData(withTimeout: -1, tag: 0)
    }

主要流程如下
1、将接收的数据保存到缓存数据中。
2、while循环去读数据,直到判断缓存是否小于8。(0-4字节为消息类型,4-8为消息长度)
3、循环中去判断缓存数据是否大于内容的长度,如果大于,则解析掉这条数据,并从缓存中删除,如果缓存数据还有大于8字节长度的数据,则循环读取数据。
如果数据长度小于获取到的内容长度,则说明出现粘包,则继续readData,继续拼接缓存数据。

相关文章

  • socket 粘包拆包处理

    粘包、拆包? 客户端或者服务端不断的发送数据包时,接收的数据会出现两个数据包粘在一起的情况,这就是TCP协议中经常...

  • TCP粘包拆包

    TCP粘包拆包定义 拆包和粘包是在socket编程中经常出现的情况,在socket通讯过程中,如果通讯的一端一次性...

  • iOS Socket封包、粘包、拆包处理

    一、封包 在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socke...

  • Socket粘包和拆包处理思路

    一旦客户端和服务器建立了Socket通信连接,接下来粘包和拆包就是一个必须要考虑的问题 本文是关于使用TCP协议下...

  • Socket粘包处理

  • Socket粘包处理

    什么是粘包 TCP有粘包现象,而UDP不会出现粘包。 TCP(Transport Control Protocol...

  • socket封包、拆包、粘包

    https://blog.csdn.net/gengbaolong/article/details/75450208

  • 即时通讯

    iOS即时通讯,从入门到“放弃”?socket的半包,粘包与分包的问题iOS 处理socket粘包问题iOS___...

  • netty学习系列八:拆包器

    一、粘包与拆包 1、发送时的粘包与拆包 TCP连接维护了一个发送缓存区。将要发送给对端的数据会由socket AP...

  • TCP协议下的粘包与拆包,如何解决

    TCP协议下的粘包与拆包,如何解决 TCP协议下的粘包与拆包,如何解决一、粘包、拆包1.1 粘包原因1.1.1 滑...

网友评论

      本文标题:Socket粘包,拆包处理

      本文链接:https://www.haomeiwen.com/subject/jwofdrtx.html