亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C# Socket系列三 socket通信的封包和拆包

2019-11-17 02:31:15
字體:
來源:轉載
供稿:網友

C# Socket系列三 socket通信的封包和拆包

通過系列二 我們已經實現了socket的簡單通信 接下來我們測試一下,在時間應用的場景下,我們會快速且大量的傳輸數據的情況!

 1    class PRogram 2     { 3         static void Main(string[] args) 4         { 5             TCPListener tcp = new TCPListener(); 6             TSocketClient client = new TSocketClient(); 7             for (int i = 0; i < 10; i++) 8             { 9                 client.SendMsg(System.Text.UTF8Encoding.Default.GetBytes("Holle Server!"));10             }11             Console.ReadLine();12         }13     }

我們通過測試代碼快速發送10條消息到服務器去,

我們看看運行結果

這樣不難看出,我們的客戶端發送了10條消息,但是服務器收到的時候變成了兩條消息,回復客戶端自然就變成兩次回復。

這是為什么呢?

我們修改一下程序一秒鐘發送一次消息試試

 1    class Program 2     { 3         static void Main(string[] args) 4         { 5             TCPListener tcp = new TCPListener(); 6             TSocketClient client = new TSocketClient(); 7             for (int i = 0; i < 5; i++) 8             { 9                 Thread.Sleep(1000);10                 client.SendMsg(System.Text.UTF8Encoding.Default.GetBytes("Holle Server!"));11             }12             Console.ReadLine();13         }14     }

運行看看,

這次對了那么分析分析到底為什么呢?

這是socket的底層,做的手腳。因為我設置socket的發送和接受緩沖區

//10K的緩沖區空間 private int BufferSize = 10 * 1024;

10k的緩沖區,

且socket的底層 發送消息會有一定間隙,雖然這個時間很短,但是我們直接for循環發送的話,時間同意很快,

因為socket.send()方法并非真實的發送數據而是把數據壓入發送緩沖區。

那么我們就明白了為什么會出現上面的情況

出現了這樣的情況我們要怎么解決呢?

時間應用場景不可能1秒鐘才一條消息啥。

我們知道了導致這個問題的原因是因為消息發送是出現了快速壓入很多發送消息到待發送緩沖區里面一起發送導致的。這樣情況就是粘包了,那么我們是不是可以考慮給每一個消息加入包標識呢?

接下來我們修改一下發送包的數據代碼

創建消息的構造體TSocketMessage

 1  /// <summary> 2     /// 底層通信消息 3     /// </summary> 4     public class TSocketMessage : IDisposable 5     { 6         /// <summary> 7         /// 消息ID 8         /// </summary> 9         public int MsgID;10         /// <summary>11         /// 消息內容12         /// </summary>13         public byte[] MsgBuffer;14 15         public TSocketMessage(int msgID, byte[] msg)16         {17             this.MsgID = msgID;18             this.MsgBuffer = msg;19         }20 21         public void Dispose()22         {23             this.Dispose(true);24             GC.SuppressFinalize(this);25         }26 27         protected virtual void Dispose(bool flag1)28         {29             if (flag1) { this.MsgBuffer = null; }30         }31     }

接下來我們創建消息包的封裝和拆分MarshalEndian

  1  public class MarshalEndian  2     {  3         //用于存儲剩余未解析的字節數  4         private List<byte> _LBuff = new List<byte>(2);  5         //默認是utf8的編碼格式  6         private UTF8Encoding utf8 = new UTF8Encoding();  7   8         //包頭1  9         const Int16 t1 = 0x55; 10         //包頭2 11         const Int16 t2 = 0xAA; 12         //字節數常量 兩個包頭4個字節,一個消息id4個字節,封裝消息長度 long 8個字節 13         const long ConstLenght = 12L; 14  15         public void Dispose() 16         { 17             this.Dispose(true); 18             GC.SuppressFinalize(this); 19         } 20  21         protected virtual void Dispose(bool flag1) 22         { 23             if (flag1) 24             { 25                 IDisposable disposable2 = this.utf8 as IDisposable; 26                 if (disposable2 != null) { disposable2.Dispose(); } 27                 IDisposable disposable = this._LBuff as IDisposable; 28                 if (disposable != null) { disposable.Dispose(); } 29             } 30         } 31  32         public byte[] Encode(TSocketMessage msg) 33         { 34             MemoryStream ms = new MemoryStream(); 35             BinaryWriter bw = new BinaryWriter(ms, new UTF8Encoding()); 36             byte[] msgBuffer = msg.MsgBuffer; 37  38             #region 封裝包頭 39             bw.Write((Int16)t1); 40             bw.Write((Int16)t2); 41             #endregion 42  43             #region 包協議 44             if (msgBuffer != null) 45             { 46                 bw.Write((Int64)(msgBuffer.Length + 4)); 47                 bw.Write(msg.MsgID); 48                 bw.Write(msgBuffer); 49             } 50             else { bw.Write((Int64)0); } 51             #endregion 52  53             bw.Close(); 54             ms.Close(); 55             bw.Dispose(); 56             ms.Dispose(); 57             return ms.ToArray(); 58         } 59  60         public List<TSocketMessage> GetDcAppMess(byte[] buff, int len) 61         { 62             //拷貝本次的有效字節 63             byte[] _b = new byte[len]; 64             Array.Copy(buff, 0, _b, 0, _b.Length); 65             buff = _b; 66             if (this._LBuff.Count > 0) 67             { 68                 //拷貝之前遺留的字節 69                 this._LBuff.AddRange(_b); 70                 buff = this._LBuff.ToArray(); 71                 this._LBuff.Clear(); 72                 this._LBuff = new List<byte>(2); 73             } 74  75             List<TSocketMessage> list = new List<TSocketMessage>(); 76             MemoryStream ms = new MemoryStream(buff); 77             BinaryReader buffers = new BinaryReader(ms, this.utf8); 78             try 79             { 80                 byte[] _buff; 81             Label_0073: 82                 //判斷本次解析的字節是否滿足常量字節數  83                 if ((buffers.BaseStream.Length - buffers.BaseStream.Position) < ConstLenght) 84                 { 85                     _buff = new byte[(int)(buffers.BaseStream.Length - buffers.BaseStream.Position)]; 86                     Array.Copy(buff, (int)buffers.BaseStream.Position, _buff, 0, _buff.Length); 87                     this._LBuff.AddRange(_buff); 88                     return list; 89                 } 90                 #region 包頭讀取 91             //循環讀取包頭 92             Label_00983: 93                 Int16 tt1 = buffers.ReadInt16(); 94                 Int16 tt2 = buffers.ReadInt16(); 95                 if (!(tt1 == t1 && tt2 == t2)) 96                 { 97                     long ttttt = buffers.BaseStream.Seek(-3, SeekOrigin.Current); 98                     goto Label_00983; 99                 }100                 #endregion101 102                 #region 包協議103                 long offset = buffers.ReadInt64();104                 #endregion105 106                 #region 包解析107                 //剩余字節數大于本次需要讀取的字節數108                 if (offset < (buffers.BaseStream.Length - buffers.BaseStream.Position))109                 {110                     int msgID = buffers.ReadInt32();111                     _buff = new byte[offset - 4];112                     Array.Copy(buff, (int)buffers.BaseStream.Position, _buff, 0, _buff.Length);113                     list.Add(new TSocketMessage(msgID, _buff));114                     //設置偏移量 然后繼續循環讀取115                     buffers.BaseStream.Seek(offset, SeekOrigin.Current);116                     goto Label_0073;117                 }118                 else if (offset == (buffers.BaseStream.Length - buffers.BaseStream.Position))119                 {120                     int msgID = buffers.ReadInt32();121                     //剩余字節數剛好等于本次讀取的字節數122                     _buff = new byte[offset - 4];123                     Array.Copy(buff, (int)buffers.BaseStream.Position, _buff, 0, _buff.Length);124                     list.Add(new TSocketMessage(msgID, _buff));125                 }126                 else127                 {128                     //剩余字節數剛好小于本次讀取的字節數 存起來,等待接受剩余字節數一起解析129                     _buff = new byte[(int)(buffers.BaseStream.Length - buffers.BaseStream.Position + ConstLenght)];130                     Array.Copy(buff, (int)(buffers.BaseStream.Position - ConstLenght), _buff, 0, _buff.Length);131                     buff = _buff;132                     this._LBuff.AddRange(_buff);133                 }134                 #endregion135 136             }137             catch { }138             finally139             {140                 if (buffers != null) { buffers.Dispose(); }141                 buffers.Close();142                 if (buffers != null) { buffers.D
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩免费在线播放| 最近2019年好看中文字幕视频| 欧美激情精品久久久久久久变态| 国产欧美一区二区三区视频| 欧美成人精品在线播放| 亚洲精品国产电影| 91精品国产高清自在线| 日韩成人在线播放| 亚洲资源在线看| 国产精品成人久久久久| 久久不射电影网| 亚洲第一网中文字幕| 久久久精品日本| 69国产精品成人在线播放| 日韩中文字幕视频在线观看| 亚洲欧美国内爽妇网| 国产有码一区二区| 欧美激情精品久久久久久大尺度| 在线色欧美三级视频| 国产一区二区黑人欧美xxxx| 色无极影院亚洲| 欧美日韩中文字幕综合视频| 日韩av电影免费观看高清| 欧美黄色片免费观看| 国产在线不卡精品| 国产成人综合精品| 国产精品第七十二页| 欧美黑人性视频| 国产精品视频免费观看www| 亚洲男人的天堂在线播放| 国产91精品网站| 最新亚洲国产精品| 国产精品久久国产精品99gif| 亚洲精品短视频| 九九热这里只有在线精品视| 成人免费高清完整版在线观看| 亚洲国产99精品国自产| 91视频-88av| 成人免费看吃奶视频网站| 欧美日韩一区二区精品| 国内揄拍国内精品少妇国语| 成人黄色av网站| 国产ts人妖一区二区三区| 亚洲色图校园春色| 欧美精品性视频| 欧美激情日韩图片| 日韩精品有码在线观看| 国产精品丝袜视频| 欧美日韩免费看| 日韩视频在线观看免费| 日韩精品福利在线| 亚洲女成人图区| 亚洲日本欧美中文幕| 国产成人a亚洲精品| 亚洲最新在线视频| 国产一区二区三区视频| 欧美亚洲午夜视频在线观看| 欧美亚洲国产视频小说| 日韩欧美国产中文字幕| 日韩成人在线视频网站| 欧美日韩999| 另类美女黄大片| 国产精品中文久久久久久久| 亚洲精品成a人在线观看| 亚洲自拍偷拍第一页| 亚洲美女av网站| 国产精品自在线| 色综合久久中文字幕综合网小说| 日本精品一区二区三区在线播放视频| 97在线观看免费| 国产精品大陆在线观看| 91国偷自产一区二区三区的观看方式| 亚洲久久久久久久久久久| 国产精品wwww| 欧美高清第一页| 在线成人中文字幕| 亚洲国产精品999| 亚洲一区999| 久久久av免费| 欧美一级大胆视频| 欧美插天视频在线播放| 精品成人国产在线观看男人呻吟| 久久国产精品偷| 欧美精品18videosex性欧美| 亚洲男人第一网站| 欧美丝袜一区二区| 国产亚洲欧美视频| 福利精品视频在线| 久久精品一区中文字幕| 国产第一区电影| 国产精品6699| 亚洲精品自拍视频| 欧美激情第一页xxx| 午夜免费久久久久| 91系列在线观看| 欧美国产第二页| 亚洲高清av在线| 97av在线视频免费播放| 色综合天天综合网国产成人网| 欧美成人精品激情在线观看| 日韩精品在线私人| 欧美一级片久久久久久久| 国产精品最新在线观看| 57pao成人永久免费视频| 久久久精品日本| 国产99久久精品一区二区永久免费| 欧美大秀在线观看| 国产精品视频久久| 欧美亚洲伦理www| 国产成人精品av| 欧美日韩国产一区中文午夜| xvideos成人免费中文版| 亚洲精品小视频| 精品毛片三在线观看| 欧美性猛交99久久久久99按摩| 91伊人影院在线播放| 国产精品久久久久久久午夜| 国产精品电影观看| xxxxxxxxx欧美| 久久精品精品电影网| 97精品免费视频| 性色av一区二区三区免费| 欧美专区国产专区| 1769国内精品视频在线播放| 伊人av综合网| 一本一本久久a久久精品牛牛影视| 亚洲最大av在线| 清纯唯美亚洲激情| 亚洲精品女av网站| 久久久免费电影| 欧美激情第三页| 欧美成人亚洲成人| 久久亚洲综合国产精品99麻豆精品福利| 欧美日韩免费区域视频在线观看| 久久久久久网站| 国产成人福利网站| 久久久精品国产| 日韩成人激情影院| 久久久久中文字幕2018| 精品福利樱桃av导航| 午夜精品视频在线| 91最新在线免费观看| 日韩在线观看av| 国产精品一二三在线| 亚洲一级一级97网| 一区二区欧美在线| 精品视频在线播放免| 国产亚洲精品久久久久久777| 在线播放国产一区中文字幕剧情欧美| 国产v综合v亚洲欧美久久| 欧洲亚洲免费视频| 免费99精品国产自在在线| 国产精品欧美亚洲777777| 亚洲美女性生活视频| 国产精品视频色| 亚洲精品在线不卡| 国产亚洲精品久久久久动| 国产精品视频内| 久久精品国产一区| 日韩精品日韩在线观看| 国产精品久久久久久亚洲影视| 欧美亚洲激情视频| 国产精品久久久久7777婷婷| 国产精品自拍网|