仅提供示例,因为每个项目对应的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)
}
}
网友评论