大家好,又見面了,我是全棧君
project正在使用長連接配接快來server溝通。是以,指定我們的協定前兩個位元組為資料長度來區分資料包
app這邊資料有兩種傳輸形式:
1.app主動請求所須要的資料;
2.app異步接收來自服務端的推送消息,也就是app這邊沒有請求。服務端主動發送資料到appclient。
整個app執行期間,它們都是在同一個連接配接上完畢的傳輸資料。是以會出現下面的問題:
1.server傳輸資料過快,出現粘包的問題,比如
1.1服務端一次發來多個推送消息;
1.2網絡不穩定,client連續發送多個請求client一次接收到所有答複。
2.client的一個請求封包,服務端的應答封包資料過大。到IP層須要進行分片,是以client這邊就會出現幾次才接收到完整的資料的情況;
首先有下面4個方法須要介紹
/**
**執行個體方法
**調用此方法以後,當套接字接收緩沖區有可用位元組的時候。會觸發onSocket:didReadData:withTag:托付方法。此時接收到的資料會出現上面說到的問題
*/
– (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
/**
**執行個體方法
**調用此方法以後。當套接字接收緩沖區有length長度的可用位元組的時候,會觸發onSocket:didReadData:withTag:托付方法,此時接收到固定長度的資料,這個固定長度就是length給出的值,當length的長度大于接收緩沖區資料的長度的時候,就會等待,直到接收到length長度的資料的時候才會觸發以上托付方法的調用
*/
– (void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
/**
**執行個體方法
**此方法功能同上,僅僅是多了幾個參數,buffer是你将接收的資料寫到的地方,offset是寫到buffer中的偏移位置
*/
– (void)readDataToLength:(NSUInteger)length
withTimeout:(NSTimeInterval)timeout
buffer:(NSMutableData *)buffer
bufferOffset:(NSUInteger)offset
tag:(long)tag;
/**
**托付方法
**此方法上面已經說到
*/
– (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)_data withTag:(long)tag。
解決方法:
client每次發送請求以後。首先僅僅接收兩個位元組的長度位元組,例如以下:
[sendSocket readDataToLength:2 withTimeout:set.timeout tag:tag];[sendSocket writeData:data withTimeout:set.timeout tag:tag];
複制
然後當有可用位元組到達套接字接收緩沖區的時候觸發下面托付方法,我們在裡面做例如以下處理,這樣既攻克了粘包的問題,也攻克了資料過大。多次接收完整的問題;
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)_data withTag:(long)tag
{
SettingData* set = [SettingData shareSettingData];
if (respondData == nil) {
respondData = [[NSMutableData alloc]init];
respondDataLen = [RequestUnit respondMessageLengthWithData:_data];
[sock readDataToLength:respondDataLen withTimeout:set.timeout tag:tag];
return;
}
[respondData appendData:[RequestUnit respondBytesToUTF8Data:_data]];
[self parserData:respondData withTag:tag];
}
複制
版權聲明:本文部落格原創文章。部落格,未經同意,不得轉載。
釋出者:全棧程式員棧長,轉載請注明出處:https://javaforall.cn/117542.html原文連結:https://javaforall.cn