美文网首页
Swift-SocketServer端粘包处理

Swift-SocketServer端粘包处理

作者: T92 | 来源:发表于2022-02-16 11:46 被阅读0次

    仅提供示例,因为每个项目对应的socket消息通讯协议几乎都是不同的,我这里每条消息的消息头占3个字节,其中第2、3字节是消息体长度(不包含消息头,大端模式)

    import UIKit
    import CocoaAsyncSocket
    
    private class WSClientDataProt {
        
        var ip = ""
        
        private let queue = OperationQueue()
        private var operation: BlockOperation?
        private var tcpCacheData = Data()
        
        func unpackMsg(data: Data){
            let operation = BlockOperation { [weak self] in
                guard let strongSelf = self else { return }
                strongSelf.tcpCacheData.append(data)
                while !strongSelf.tcpCacheData.isEmpty {
                    var lc: UInt16 = 0
                    guard strongSelf.tcpCacheData.count >= 3 else { break }
                    (strongSelf.tcpCacheData as NSData).getBytes(&lc, range: NSMakeRange(1, 2))
                    let len = Int(UInt16(bigEndian: lc)) + 3
                    guard let body = strongSelf.tcpCacheData.getSubData(start: 0, count: len) else { break }
                    if currntAppMode == .microPhone{
                        WSMicroManager.shared.dealMicroData(data: body)
                    }else{
                        WSCameraManager.shared.dealCameraData(data: body)
    //                    print("摄像机端收到数据:\(body.hexString())")
                    }
                    strongSelf.removeCacheData(start: 0, num: len)
                }
            }
            if let op = self.operation {
                operation.addDependency(op)
            }
            queue.addOperation(operation)
            self.operation = operation
        }
        
        private func removeCacheData(start: Int, num: Int){
            guard start >= 0 && num >= 0 else { return }
            guard tcpCacheData.count >= start + num else { return }
            let startIndex = tcpCacheData.index(tcpCacheData.startIndex, offsetBy: start)
            let endIndex = tcpCacheData.index(tcpCacheData.startIndex, offsetBy: start + num)
            let range = startIndex..<endIndex
            tcpCacheData.removeSubrange(range)
        }
    }
    
    class WSSocketDataManager: NSObject {
        
        static let shared = WSSocketDataManager()
        private override init() { }
        
        private var clientDataDic = [String:WSClientDataProt]()
        
        func didReceiveData(data: Data, TCPSock: GCDAsyncSocket? = nil){
            //tcp
            if let sock = TCPSock {
                guard let add = sock.connectedHost else { return }
                if let client = clientDataDic[add] {
                    client.unpackMsg(data: data)
                }else{
                    let clientData = WSClientDataProt()
                    clientData.ip = add
                    clientDataDic[add] = clientData
                    clientData.unpackMsg(data: data)
                }
            }
            //udp
            else{
                if currntAppMode == .microPhone{
                    WSMicroManager.shared.dealMicroData(data: data)
                }else{
                    WSCameraManager.shared.dealCameraData(data: data)
                }
            }
        }
        //socket断开时调用
        func removeSocketData(sock: GCDAsyncSocket){
            guard let add = sock.connectedHost else { return }
            clientDataDic.removeValue(forKey: add)
        }
        
    }
    

    相关文章

      网友评论

          本文标题:Swift-SocketServer端粘包处理

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