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

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

寫自己的socket框架(二)

2019-11-17 03:00:17
字體:
來源:轉載
供稿:網友

寫自己的socket框架(二)

1、開始正常監聽以后,就要開始接受數據了,整體流程圖如下:

2、上一節看到我們在程序初始化的時候,初始化了很多個SocketConnection,用于管理客戶端的鏈接,那應用層如何來操作,又什么時候來接受數據?于是我們便有了Socketsession,用于給應用層來管理整個會話過程,代碼如下:

public class SocketSession : IDisposable    {        public string SessionId { get; PRivate set; }        private System.Net.Sockets.Socket _connectSocket;        private iprotocol _protocol;        private SocketConnection _connect;        public SocketConnection Connection { get { return _connect; } }        private MemoryStream _memStream;        private delegate void ReceiveDataHandler(SocketAsyncEventArgs e);        private ReceiveDataHandler ReceiveHandler;        private delegate void ReceiveReadPackageHandler(byte[] b, int offset, SocketAsyncEventArgs e);        private ReceiveReadPackageHandler ReadPackageHandler;        public System.Net.Sockets.Socket ConnectSocket        {            get            {                return _connectSocket;            }            private set { }        }        public SocketSession(string sessionId)        {            this.SessionId = sessionId;        }        public SocketSession(System.Net.Sockets.Socket client, SocketConnection connect)            : this(Guid.NewGuid().ToString())        {            this._connectSocket = client;            this._connect = connect;            this._protocol = connect.Pool.AppServer.AppProtocol;            _memStream = new MemoryStream();            ReceiveHandler = ReceiveData;            ReadPackageHandler = this.ReadPackage;        }        internal void ReceiveData(SocketAsyncEventArgs e)        {            if (e.SocketError != SocketError.Success)            {                this.Close();                return;            }            if (e.BytesTransferred <= 0)            {                this.Close();                return;            }            try            {                if (this.Connection.Flag == SocketFlag.Busy)                {                    byte[] buffer = new byte[e.BytesTransferred];                    Array.Copy(e.Buffer, 0, buffer, 0, e.BytesTransferred);                    ReadPackage(buffer, 0, e);                    buffer = null;                }            }            catch (Exception ex)            {                this.Close();                return;            }        }        internal void ReceiveAsync(SocketAsyncEventArgs e)        {            if (e == null)            {                return;            }            bool isCompleted = true;            try            {                isCompleted = this._connectSocket.ReceiveAsync(e);            }            catch (Exception ex)            {                LogHelper.Debug(this.SessionId + ex.ToString());                this.Close();            }            if (!isCompleted)            {                this.ReceiveHandler.BeginInvoke(e, ReceiveHandlerCallBack, ReceiveHandler);            }        }        void ReceiveHandlerCallBack(IAsyncResult result)        {            try            {                (result.AsyncState as ReceiveDataHandler).EndInvoke(result);            }            catch (Exception e)            {                LogHelper.Debug(e.Message);            }        }        internal void OnDataRecevied(SessionEventArgs arg)        {            if (DataRecevied != null)            {                this._memStream.SetLength(0);                DataRecevied.Invoke(this, arg);            }        }        internal void Close()        {            try            {                this._connectSocket.Close();            }            catch (Exception ex)            {                LogHelper.Debug("關閉socket異常" + ex.ToString());            }            if (this.Closed != null)            {                this.Closed();            }        }        internal Action Closed;        internal Action<SocketSession, SessionEventArgs> DataRecevied;        public void Dispose()        {            if (_memStream != null)            {                _memStream.Close();                _memStream.Dispose();                _memStream = null;            }        }        public void Send(byte[] data)        {            try            {                if (this.Connection.Flag == SocketFlag.Busy)                {                    this._connectSocket.Send(data);                }            }            catch (Exception ex)            {                this.Close();            }        }        private void ReadPackage(byte[] data, int offset, SocketAsyncEventArgs e)        {            if (data == null || data.Length == 0)            {                return;            }            if (offset >= data.Length)            {                return;            }            if (offset == 0)            {                if (_memStream.Length > 0)                {                    _memStream.Write(data, 0, data.Length);                    data = _memStream.ToArray();                }            }            //粘包處理            OnReceivedCallBack(data, offset, e);            data = null;        }        private void OnReceivedCallBack(byte[] buffer, int offset, SocketAsyncEventArgs e)        {            byte[] data = this._protocol.OnDataReceivedCallBack(buffer, ref offset);            if (offset == -1)            {                this.Close();                return;            }            if (data == null || data.Length == 0)            {                this._memStream.Write(buffer, offset, buffer.Length - offset);                this.ReceiveAsync(e);                return;            }            SessionEventArgs session_args = new SessionEventArgs();            session_args.Data = data;            this.OnDataRecevied(session_args);            if (offset < buffer.Length)            {                this.ReadPackageHandler.BeginInvoke(buffer, offset, e, ReadPackageCallBack, ReadPackageHandler);            }            else            {                this.ReceiveAsync(e);            }            data = null;        }        void ReadPackageCallBack(IAsyncResult result)        {            try            {                (result.AsyncState as ReceiveReadPackageHandler).EndInvoke(result);            }            catch (Exception ex)            {                LogHelper.Debug(ex.Message);            }        }    }
View Code

細心的童鞋可以發現,在ReceiveAsync方法里面,接收數據的地方,當同步接收完成的時候,我們調用了一個異步委托ReceiveHandler.BeginInvoke。

在解析出一個獨立的包,并且緩沖區的數據里面還有多余的包的時候,我們也調用了一個異步的委托ReadPackageHandler.BeginInvoke。

如果緩沖區比較大,比如我現在是8K,而單個包很小,客戶端又發送比較頻繁的時候。會導致在解析包的時候,形成一個短暫的遞歸。遞歸就會不停的壓堆,資源得不到釋放。

運行一段時間后,有可能導致OutOfMemoryException,如果一直是同步接收數據,在Receive的地方,也有可能形成一個遞歸。于是便采用了異步調用的方式。

3、因為socket屬于無邊界的,代碼層面的每一次Send,并不是真正意義上的直接發送給服務器,而只是寫到了緩沖區,由系統來決定什么時候發。如果客戶 端發送非常頻繁的情況下,就可能導致服務器從緩沖區取出來的包,是由多個包一起組成的。從緩沖區取出來的包,并不能保證是一個獨立的應用層的包,需要按既定的協議來解析包。

我們先假定一個簡單的協議,一個包的前4個字節,表明這個包內容的長度。代碼如下:

public class DefaultProtocol : IProtocol    {        public byte[] OnDataReceivedCallBack(byte[] data, ref int offset)        {            int length = BitConverter.ToInt32(data, offset);            int package_head = 4;            int package_length = length + package_head;            byte[] buffer = null;            if (length > 0)            {                if (offset + package_length <= data.Length)
上一篇:C#匿名委托

下一篇:C#制作在線升級程序

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲美女av在线播放| 国产亚洲精品久久久优势| 国产成人在线亚洲欧美| 精品免费在线视频| 欧美体内谢she精2性欧美| 久久天天躁日日躁| 51ⅴ精品国产91久久久久久| 一区二区三区回区在观看免费视频| 国产精品普通话| 亚洲精品综合久久中文字幕| 国产精品久久一| 51ⅴ精品国产91久久久久久| 久久精品视频一| 91经典在线视频| 国产精品91久久久| 国产欧美精品久久久| 国产精品自拍视频| 亚洲视频国产视频| 欧美性猛交99久久久久99按摩| 91wwwcom在线观看| 久久久久日韩精品久久久男男| 久久高清视频免费| 亚洲欧美日韩爽爽影院| 久久99青青精品免费观看| 97国产suv精品一区二区62| 青青草原一区二区| 亚洲成人亚洲激情| 91精品久久久久久久久久久| 欧美日韩亚洲精品一区二区三区| 欧美日韩免费一区| 亚洲人av在线影院| 日韩黄在线观看| 亚洲欧美精品中文字幕在线| 国产精品久久久久久久av电影| 成人做爰www免费看视频网站| 国产精品视频在线观看| 国产精品久久久久久久久借妻| 亚洲国产黄色片| 国产成人短视频| 欧美日韩国产精品一区二区三区四区| 92版电视剧仙鹤神针在线观看| 欧美日韩免费区域视频在线观看| 国产精品av免费在线观看| 国产一区深夜福利| 亚洲成人网在线| 亚洲**2019国产| 国产精品青草久久久久福利99| 亚洲精品少妇网址| 久久精品视频va| 国产91久久婷婷一区二区| 97精品国产97久久久久久免费| 国产一区二区在线播放| 欧美精品videofree1080p| 久久免费视频在线观看| 亚洲成人aaa| 日韩在线一区二区三区免费视频| 国产精品成人免费电影| 国产精品欧美激情| 国外成人在线直播| 日韩av中文字幕在线播放| 精品无人区乱码1区2区3区在线| 欧美视频在线观看免费| 91精品国产沙发| 日韩美女中文字幕| 成人福利视频在线观看| 国产精品久久久久7777婷婷| 国产精品精品久久久| 欧美有码在线视频| 亚洲欧洲国产一区| 亚洲美女免费精品视频在线观看| 粗暴蹂躏中文一区二区三区| 欧美成人第一页| 青草成人免费视频| 操91在线视频| 欧美成人全部免费| 国产日韩精品在线观看| 国产成人在线一区二区| 国产国语videosex另类| 欧美黄网免费在线观看| 亚洲乱码av中文一区二区| 亚洲第一在线视频| 91夜夜未满十八勿入爽爽影院| 色综合久久中文字幕综合网小说| 国产精品丝袜久久久久久高清| 高清欧美性猛交xxxx| 亚洲一区二区中文| 国产精选久久久久久| 亚洲免费成人av电影| 国产精品免费久久久久久| 日韩中文字幕免费视频| 午夜精品久久久久久久久久久久久| 国内揄拍国内精品少妇国语| 亚洲a区在线视频| 国产精品免费电影| 精品久久久久久久久久ntr影视| 亚洲自拍在线观看| 国产精品精品视频| 91精品国产色综合久久不卡98| 日韩高清人体午夜| 欧美性猛交xxxx乱大交蜜桃| 久久中文精品视频| 在线观看日韩欧美| 欧美日本高清一区| 91在线视频一区| 青青久久av北条麻妃海外网| 成人性生交xxxxx网站| 亚洲精品乱码久久久久久按摩观| 992tv成人免费视频| 国产视频综合在线| 国产日产欧美精品| 欧美视频在线观看 亚洲欧| 精品中文字幕在线2019| 欧美精品videosex性欧美| 国产精品视频一区二区高潮| 欧美日韩黄色大片| 最近的2019中文字幕免费一页| 三级精品视频久久久久| 日韩亚洲欧美中文在线| 国产日韩在线免费| 国产精品99久久久久久www| 7m第一福利500精品视频| 91国产视频在线| 亚洲精品国产精品久久清纯直播| 日韩av大片免费看| 国产一区二区三区免费视频| 日韩精品中文字幕在线观看| 2019av中文字幕| 亚洲欧美制服中文字幕| 狠狠操狠狠色综合网| 欧美最顶级丰满的aⅴ艳星| 亚洲性生活视频| 欧美激情第6页| 91av国产在线| 中文字幕精品www乱入免费视频| 国产日韩欧美在线播放| 亚洲欧美第一页| 久久精品99久久久久久久久| 欧美综合激情网| 国产精品久久久av久久久| 国产精品18久久久久久麻辣| 国产丝袜精品视频| 91在线直播亚洲| 欧美黑人性生活视频| 97精品国产97久久久久久| 国产不卡av在线| 亚洲品质视频自拍网| 欧美激情高清视频| 国产精品久久久91| 国产欧美一区二区| 正在播放欧美视频| 精品亚洲国产成av人片传媒| 亚洲精品成人久久久| 理论片在线不卡免费观看| 欧美大片免费观看| 国产日本欧美视频| 久久精品精品电影网| 在线观看欧美日韩| 成人欧美一区二区三区黑人孕妇| 国产精品日韩一区| 日韩不卡中文字幕| 久久天堂电影网| 国产午夜精品视频| 欧美极品美女视频网站在线观看免费| 成人h视频在线观看播放|