高效的tcp資料拆包器 接收器,每秒拆1kb的包達到30萬以上
/// 資料同步協義資料接收器
///
/// /// 主要功能有
/// 1.將乙個tcpsocket的所有資料所有接收
/// 2.解析協義
/// 3.解析完畢後的協義呼叫 handler通知外部處理
/// 4.定義乙個協**析執行緒不停的解析協義
///
public class tcpreceiver : idisposable
/// /// 資料同步協義資料接收器 例項
///
/// 協議頭
/// 協議尾
public tcpreceiver(byte protocolhead, byte protocolfoot = null)
#endregion
/// /// 最大單個協義體資料長度,預設10mb
///
private int maxprotocolbinary = 1024 * 1024 * 10;
/// /// 最大單個協義體資料長度
///
public int maxprotocolbinary
set
}/// /// 是否正在執行
///
public bool isruning
private task task = null;
/// /// 當前處理解析協義的執行緒
///
public task praseprotocoltask
}/// /// 接收資料處理事件
///
public actionprotocolreceivedhandler
/// /// 是從哪個節點接收的資料
///
public socket handler
#region 接收資料加入到佇列
/// /// 接收資料處理集合,預設開放1mb的空間
///
// protected system.collections.generic.queuebytequeue = new queue(1024 * 1024);
/// /// 預設開放500空間,100萬次單純加入用時95毫秒
///
private queuereceivebytearrayqueue = new queue(500);
/// /// 接入佇列處理器
///
protected queuereceivebytearrayqueue
}#if debug
//private int cuount = 1;
#endif
/// /// 接收資料
///
public void receive(byte buff)
}#endregion
#region 執行緒控制
/// /// 停止解析協義
///
public void stopparseprotocol()
}#endregion
#region 解析協義資料
/// /// 分包用包頭
///
private byte packagehead = new byte ;//0x7e
/// /// 分包用包頭
///
public byte packagehead
set}
}/// /// 分包用包尾
///
private byte packagefoot = new byte ;
/// /// 分包用包尾
///
public byte packagefoot
set}
}/// /// 用於處理資料協義的功能
///
listbytes = new list();
/// /// 預設開 3mb的資料接收緩衝區,假設超過3mb則資料會掛掉
///
//private byte bytebuff = null;
/// /// 協義資料實體佇列,已經進行拆包後的協義資料
///
private queueprotocolentityqueue = new queue(500);
/// /// 找到分包用包頭
///
bool findpackagehead = false;
/// /// 找包頭的當著序號
///
int findheadindex = 0;
/// /// 找包尾
///
int findfootindex = 0;
/// /// 解析協義方法
/// 之所以先所有放到乙個query裡是進行高速的接收
///
///
public void praseprotocol()
}/// /// 處理佇列中的資料刪除包頭,包尾巴
///
public void processbytes()
}if (arr != null)
//加入到對像集合
bytes.add(b);
//3.從集合的前面開始取資料.找包頭,進行拆包
#region 找包頭
//等於包資料
if (packagehead.length > 0 && b == packagehead[findheadindex] && !findpackagehead)
//這裡取乙個完整包
byte bytefarm = bytes.take(bytes.count - packagehead.length).toarray();
//假設是有效的資料
if (bytefarm.length > packagehead.length)
//開始從 bytes 中移除資料
bytes.clear();
//加入包頭
bytes.addrange(packagehead);
}//包頭找完則找下一位元組
continue;
}else
}else
}#endregion
#region 找包尾
if (packagefoot != null && packagefoot.length > 0 && findpackagehead)
//開始從 bytes 中移除資料
bytes.clear();
}findpackagehead = false;
//包尾找完則找下一位元組
continue;
}else
}else
}#endregion}}
//4.又一次組成乙個byte 進行資料解析
lock (protocolentityqueue)}}
}}
else
}#endregion
/// /// 析構方法
///
public void dispose()
}
用法 tcpreceiver rece = new tcpreceiver();
//將接收到的資料增加處理
rece .receive(buff);
另起乙個執行緒進行處理
while(true)
rece .praseprotocol();
TCP粘包 拆包
tcp粘包 拆包 客戶端發服務端傳送了兩個資料報a和b 粘包 服務端一次性接收到了a和b 拆包 服務端第一次接收了a和b的一部分,第二次接收到了b的剩餘部分 粘包 拆包原因 1 應用程式寫入的位元組大小 socket傳送緩衝區大小 2 tcp分段 tcp data部分的大小 mss max segm...
TCP粘包,拆包
粘包 拆包表現形式 現在假設客戶端向服務端連續傳送了兩個資料報,用packet1和packet2來表示,那麼服務端收到的資料可以分為三種,現列舉如下 第一種情況,接收端正常收到兩個資料報,即沒有發生拆包和粘包的現象,此種情況不在本文的討論範圍內。第二種情況,接收端只收到乙個資料報,由於tcp是不會出...
TCP粘包 拆包
粘包 拆包問題是網路比較底層的問題,在資料鏈路層 網路層以及傳輸層都有可能發生。我們日常的網路應用開發大都在傳輸層進行,由於udp有訊息保護邊界,不會發生粘包拆包問題,因此粘包拆包問題只發生在tcp協議中。假設客戶端向服務端連續傳送了兩個資料報,用packet1和packet2來表示,那麼服務端收到...