1. 程式人生 > >關於IOS一些有的沒的 – TCP資料傳輸粘包

關於IOS一些有的沒的 – TCP資料傳輸粘包

TCP資料傳輸粘包

  • 場景
    在工作中用到一個模組,一個房間,使用者在其中進行聊天,視訊,互動以及何種資料的傳輸,採用的方案是採用TCP/IP通訊協議及標準的socket應用開發程式設計
  • 問題
    其中遇到一個現象,資料粘包,具體體現是:在一段較短的時間內,伺服器向客戶端傳送了不止一組資料,這些資料本應該一組一組傳送,但是因為TCP協議本身原因,伺服器收集到一定的資料之後合成了一包傳送,導致資料接收出現了問題比如:

    需要傳送的資料為:  A + B + C + D 合成一包之後接收端收到處理的只有 A ,後邊的資料沒有處理
    
  • 原因

    • a 傳送方:TCP為了提高傳輸效率(TCP 面向連線,提供高可靠性服務,UDP無連線,提供高效率服務),往往要收集到足夠多的資料後才傳送一包資料,若連續幾次傳送的資料都少,則會優化演算法把資料合成一包傳送出去(這是由TCP協議本身造成的)
    • b 接收方:接收方接收資料不及時導致的
  • 解決

    • a 傳送方:TCP本身提供了強制資料立即傳送的操作指令Push,接到這個指令則不會等緩衝區滿,會立即傳送
    • b 接收方:優化,精簡接收程序工作量,程序優先順序提供
  • PS

    UPD不會出現這種情況因為他有訊息邊界可以區分開,而類似的,移動端和伺服器端共同商議一個邊界,在移動端進行資料分割
    例如:  A + B + C + D ------> A$%^& + B$%^& + C$%^& + D$%^&
          接收方根據$%^&來分開A,B,C,D來處理
    
  • 程式碼

while(rangeLen.location
!= NSNotFound) { NSData *optionData = [allData subdataWithRange:NSMakeRange(0, rangeLen.location)]; NSDictionary *dic; NSError *error = nil; dic = [NSJSONSerialization JSONObjectWithData:optionData options:NSJSONReadingMutableContainers error:&error]; [self.delegate
receiveData:error ? error.localizedDescription : dic]; NSRange temp = NSMakeRange((rangeLen.location + rangeLen.length), (allData.length-(rangeLen.location+rangeLen.length))); allData = [allData subdataWithRange:temp]; rangeLen =[allData rangeOfData:subData options:0 range:NSMakeRange(0, allData.length)]; }