高效的TCP資料拆包器

2021-09-08 12:56:41 字數 3765 閱讀 6982

高效的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來表示,那麼服務端收到...