<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      eaglet

      本博專注于基于微軟技術(shù)的搜索相關(guān)技術(shù)
        博客園  :: 首頁  :: 新隨筆  :: 聯(lián)系 :: 訂閱 訂閱  :: 管理

      .Net 下通過緩存提高TCP傳輸速度

      Posted on 2009-11-04 13:01  eaglet  閱讀(8917)  評論(16)    收藏  舉報

          .Net 提供了一個NetworkStream 用于TCP 的讀寫,實際使用時發(fā)現(xiàn)直接操作效率很低,哪怕把TCP 的發(fā)送緩存和接受緩存設(shè)置很大也沒有太大提高。后來在對 NetworkStream 讀寫前設(shè)置了緩存,性能一下子提高了很多。

          從實際測試結(jié)果看設(shè)置自己的寫緩存,對性能的提升最為顯著。我分析了一下,其原因很可能是在向NetworkStream 序列化對象時,序列化程序調(diào)用了大量的Write 方法向NetworkStream寫入數(shù)據(jù),每次向NetworkStream寫入數(shù)據(jù),數(shù)據(jù)被首先寫入TCP的發(fā)送緩存,并且由調(diào)用線程設(shè)置一個信號通知.Net framework 內(nèi)部的TCP線程發(fā)送緩沖區(qū)中已經(jīng)有數(shù)據(jù),TCP線程被激活并讀取發(fā)送緩沖區(qū)中的數(shù)據(jù),組包并向網(wǎng)卡寫入數(shù)據(jù)。頻繁的調(diào)用 NetworkStream.Write 寫入小塊數(shù)據(jù)將導(dǎo)致調(diào)用線程和TCP線程反復(fù)切換,并大量觸發(fā)網(wǎng)卡中斷,導(dǎo)致發(fā)送效率低下。如果我們在發(fā)送前將數(shù)據(jù)緩存并按較大的數(shù)據(jù)塊發(fā)送給TCP線程,則大大減少線程切換和網(wǎng)卡中斷數(shù)量,從而大大提高傳輸效率。

          問題到這里還沒有結(jié)束,我們發(fā)送的對象往往較大,如果我們將發(fā)送對象全部序列化到buffer中再發(fā)送,那么勢必占用大量內(nèi)存,實際上我們無法忍受這種對內(nèi)存無限制申請的行為,試想一個1G大小的對象,我們在發(fā)送前為它另外再開辟1個G的內(nèi)存來緩存,對于系統(tǒng)來說簡直是無法忍受。由于我們用.net 發(fā)送數(shù)據(jù),我們在發(fā)送時需要將對象序列化到流中,而不能像 C/C++那樣直接通過指針來讀取數(shù)據(jù)(當(dāng)然你也可以用unsafe代碼,但這種方式會帶來其他問題,而且并不為大家所推薦),所以我們需要開發(fā)一個專門用 TCP 發(fā)送緩存的流來處理讀寫前的緩存。為此我開發(fā)了一個 TcpCacheStream 類,這個類被用在讀寫 NetworkStream 前先進(jìn)行緩存。

          調(diào)用方法很簡單

         

      • 發(fā)送過程
      object msg;
      //初始化 msg 過程省略
      System.Net.Sockets.NetworkStream _ClientStream;
      //初始化 _ClientStream 過程省略
       
      //創(chuàng)建TcpCacheStream 
      TcpCacheStream tcpStream = new TcpCacheStream(_ClientStream);
       
      //二進(jìn)制序列化 msg 對象到 TcpCacheStream 
      IFormatter formatter = new BinaryFormatter();
      formatter.Serialize(tcpStream, msg);
       
      //將緩存中最后一包的數(shù)據(jù)發(fā)送出去
      tcpStream.Flush();

        

      • 接收過程
       
      System.Net.Sockets.NetworkStream _ClientStream;
      //初始化 _ClientStream 過程省略
       
      //創(chuàng)建TcpCacheStream 
      TcpCacheStream tcpStream = new TcpCacheStream(_ClientStream);
       
      //從 TcpCacheStream 二進(jìn)制反序列化
      IFormatter formatter = new BinaryFormatter();
      objcet result = formatter.Deserialize(tcpStream);

      TcpCacheStream 類為調(diào)用者封裝了緩存的過程,這個緩存過程實際并不復(fù)雜,發(fā)送時數(shù)據(jù)先寫入TcpCacheStream的buf中,當(dāng)buf滿后才向NetworkStream 寫入數(shù)據(jù),否則只緩存。由于最后一包不能保證正好填滿buf,我們在寫入數(shù)據(jù)后一定要調(diào)用 Flush 方法,將所有數(shù)據(jù)都發(fā)送出去。接收的過程反過來,如果buf中沒有數(shù)據(jù),就先將數(shù)據(jù)讀入到buf中,然后再COPY給調(diào)用者,如果已經(jīng)有數(shù)據(jù)則直接COPY給調(diào)用者。

       

      TcpCacheStream 的代碼如下:

          [Serializable]
          public class TcpCacheStream : Stream
          {
              #region Private fields
              const int BUF_SIZE = 4096;
              private byte[] _Buf = new byte[BUF_SIZE];
       
              private MemoryStream _CacheStream = new MemoryStream(BUF_SIZE);
              private NetworkStream _NetworkStream;
       
              private int _BufLen = 0;
       
              #endregion
       
              #region Private properties
       
              private MemoryStream CacheStream
              {
                  get
                  {
                      return _CacheStream;
                  }
              }
       
              #endregion
       
       
              #region Public properties
       
              /// <summary>
              /// get or set the Network Stream
              /// </summary>
              public NetworkStream NetworkStream
              {
                  get
                  {
                      return _NetworkStream;
                  }
              }
       
              #endregion
       
       
              public TcpCacheStream(NetworkStream networkStream)
              {
                  _NetworkStream = networkStream;
              }
       
              #region Implement stream class
       
              public override bool CanRead
              {
                  get
                  {
                      return true;
                  }
              }
       
              public override bool CanSeek
              {
                  get
                  {
                      return false;
                  }
              }
       
              public override bool CanWrite
              {
                  get
                  {
                      return true;
                  }
              }
       
              public override void Flush()
              {
                  NetworkStream.Write(_Buf, 0, _BufLen);
                  NetworkStream.Flush();
              }
       
              public override long Length
              {
                  get
                  {
                      throw new Exception("This stream can not seek!");
                  }
              }
       
              public override long Position
              {
                  get
                  {
                      throw new Exception("This stream can not seek!");
                  }
       
                  set
                  {
                      throw new Exception("This stream can not seek!");
                  }
              }
       
              public override int Read(byte[] buffer, int offset, int count)
              {
                  int len = 0;
       
                  //If cache is not empty, read from cache
                  if (CacheStream.Length > CacheStream.Position)
                  {
                      len = CacheStream.Read(buffer, offset, count);
                      return len;
                  }
       
                  //Fill cache
                  len = NetworkStream.Read(_Buf, 0, BUF_SIZE);
       
                  if (len == 0)
                  {
                      return 0;
                  }
       
                  CacheStream.Position = 0;
                  CacheStream.Write(_Buf, 0, len);
                  CacheStream.SetLength(len);
                  CacheStream.Position = 0;
       
                  len = CacheStream.Read(buffer, offset, count);
       
                  return len;
              }
       
              public override long Seek(long offset, SeekOrigin origin)
              {
                  throw new Exception("This stream can not seek!");
              }
       
              public override void SetLength(long value)
              {
                  throw new Exception("This stream can not seek!");
              }
       
              public override void Write(byte[] buffer, int offset, int count)
              {
                  if (offset + count > buffer.Length)
                  {
                      throw new ArgumentException("Count + offset large then buffer.Length");
                  }
       
                  int remain = count - (BUF_SIZE - _BufLen);
       
                  if (remain < 0)
                  {
                      Array.Copy(buffer, offset, _Buf, _BufLen, count);
                      _BufLen = BUF_SIZE + remain;
                  }
                  else
                  {
                      Array.Copy(buffer, offset, _Buf, _BufLen, BUF_SIZE - _BufLen);
                      NetworkStream.Write(_Buf, 0, _Buf.Length);
       
                      Array.Copy(buffer, offset + BUF_SIZE - _BufLen, _Buf, 0, remain);
       
                      _BufLen = remain;
                  }
              }
       
              #endregion
          }
      主站蜘蛛池模板: 国产在线98福利播放视频| 成人午夜免费无码视频在线观看 | 嫩b人妻精品一区二区三区| 成人深夜节目在线观看| 国产无套精品一区二区| 日本不卡的一区二区三区| 国产久免费热视频在线观看 | 亚洲成在人线在线播放无码| 青青草国产自产一区二区| 嵊泗县| 亚洲午夜理论无码电影| 精品一区二区三区四区色| 看亚洲黄色不在线网占| 97在线视频人妻无码| 天堂中文8资源在线8| 国产桃色在线成免费视频| 亚洲日本韩国欧美云霸高清| 视频一区视频二区卡通动漫| 久久人妻无码一区二区三区av| 亚洲国产午夜精品福利| 亚洲欧美综合中文| 又爽又大又黄a级毛片在线视频| 天堂mv在线mv免费mv香蕉| 国产AV福利第一精品| 久热天堂在线视频精品伊人| 99在线国内在线视频22| 免费看欧美日韩一区二区三区| 精品福利视频一区二区三区| 亚欧成人精品一区二区乱| 日韩av片无码一区二区不卡| 国产69精品久久久久99尤物| 亚洲一区二区三区十八禁| 国产乱色国产精品免费视频| 欧美成人无码a区视频在线观看| 国产呻吟久久久久久久92| 日韩国产成人精品视频| 国内精品伊人久久久久av| 中文字幕一区日韩精品| 亚洲AV无码久久精品日韩| 性一交一黄一片| 99精品国产一区在线看|