NSData:dataWithBytes:length:詳解 TCP/UDP/Socket粘包處理

先上代碼

    NSString *str = @"i'm a test string";
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    NSInteger dataLength = data.length;
    NSData *lengthData = [NSData dataWithBytes:&dataLength length:8];
    NSData *newLengthData = [lengthData subdataWithRange:NSMakeRange(0, 4)];

    NSInteger getDataLength = 0;
    [newLengthData getBytes:&getDataLength length:sizeof(getDataLength)];
    
    
    NSInteger getDataLength1 = 0;
    [lengthData getBytes:&getDataLength1 length:8];

這里解釋一下代碼:

NSData *lengthData = [NSData dataWithBytes:&dataLength length:8];

整行代碼表示將dataLength長(zhǎng)度信息轉(zhuǎn)換成NSData二進(jìn)制數(shù)據(jù),這里的8表示生成一個(gè)8字節(jié)的容量,
&dataLength&是取地址符。
有時(shí)候你還能見到這種寫法:
NSData *lengthData = [NSData dataWithBytes:&dataLength length:sizeof(dataLength)];
其實(shí)意思是一樣的,因?yàn)镹SInteger在iOS里占8個(gè)字節(jié)

接下來(lái):
NSData *newLengthData = [lengthData subdataWithRange:NSMakeRange(0, 4)];
這個(gè)意思是截取前4個(gè)字節(jié),為什么只接前4個(gè)字節(jié)?因?yàn)榇蟛糠智闆r下前4個(gè)字節(jié)就是完整的信息,后面4個(gè)字節(jié)全是0,試了將MAX_INT轉(zhuǎn)成data,前4個(gè)字節(jié)也完全可以存儲(chǔ)完整的信息。

最后:

    NSInteger getDataLength1 = 0;
    [lengthData getBytes:&getDataLength1 length:8];

將data轉(zhuǎn)成NSInteger獲取到data的實(shí)際長(zhǎng)度

使用場(chǎng)景一:socket通信粘包處理
當(dāng)讀取到數(shù)據(jù)寫入,先將數(shù)據(jù)加入到緩沖區(qū)

self.dataBuffer = [NSMutableData data];
[self.dataBuffer appendData:readData];

此處的readData為數(shù)據(jù)流讀出的某個(gè)完整數(shù)據(jù)的一部分,appendData:readData這個(gè)代碼可能執(zhí)行多次
截取前4個(gè)字節(jié)(這個(gè)字節(jié)數(shù)不一定要4個(gè)字節(jié) ,完全可以自己定義,跟服務(wù)器約定好就可以)

    NSInteger dataLength = 0;
    [self.dataBuffer getBytes:&getDataLength1 length:8];
    if (self.dataBuffer.length >= dataLength+4) {
          //取出我們想要的數(shù)據(jù)
          NSData *completeData = [self.dataBuffer subdataWithRange:NSMakeRange(4, dataLength)];
          //然后處理取出來(lái)的數(shù)據(jù)
          //略.........
          //移除已經(jīng)拆包的數(shù)據(jù)
          [self.dataBuffer setData:[self.dataBuffer subdataWithRange:NSMakeRange(4+dataLength, self.dataBuffer.length - 4 - dataLength)]];
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容