public int ReceiveOnce() { try { if (!Monitor.TryEnter(this, 1000)) { return(-1); //進不去先離開 } if (!this.mreIsReceiving.WaitOne(10)) { return(0); //接收中先離開 } this.mreIsReceiving.Reset(); //先卡住, 不讓後面的再次進行 var ea = new CtkProtocolEventArgs() { Sender = this, }; ea.TrxMessage = new CtkProtocolBufferMessage(1518); var trxBuffer = ea.TrxMessage.ToBuffer(); trxBuffer.Length = this.WorkSocket.Receive(trxBuffer.Buffer, 0, trxBuffer.Buffer.Length, SocketFlags.None); if (trxBuffer.Length == 0) { return(-1); } this.OnDataReceive(ea); } catch (Exception ex) { this.OnErrorReceive(new CtkProtocolEventArgs() { Message = "Read Fail" }); //當 this.ConnSocket == this.WorkSocket 時, 代表這是 client 端 this.Disconnect(); if (this.ConnSocket != this.WorkSocket) { CtkNetUtil.DisposeSocketTry(this.WorkSocket); //執行出現例外, 先釋放Socket } throw ex; //同步型作業, 直接拋出例外, 不用寫Log } finally { try { this.mreIsReceiving.Set(); /*同步型的, 結束就可以Set*/ } catch (ObjectDisposedException) { } if (Monitor.IsEntered(this)) { Monitor.Exit(this); } } return(0); }
public void Disconnect() { try { this.mreIsReceiving.Set(); /*僅Set不釋放, 可能還會使用*/ } catch (ObjectDisposedException) { } try { this.mreIsConnecting.Set(); /*僅Set不釋放, 可能還會使用*/ } catch (ObjectDisposedException) { } CtkNetUtil.DisposeSocketTry(this.m_workSocket); CtkNetUtil.DisposeSocketTry(this.m_connSocket); this.OnDisconnect(new CtkProtocolEventArgs() { Message = "Disconnect method is executed" }); }
public int ConnectTryStart() { if (this.IsOpenRequesting || this.IsRemoteConnected) { return(0); } //if (this.IsLocalReadyConnect) return; //同步連線是等到連線才離開method, 不需判斷 IsLocalReadyConnect try { if (!Monitor.TryEnter(this, 3000)) { return(-1); // throw new CtkException("Cannot enter lock"); } if (!this.mreIsConnecting.WaitOne(10)) { return(0); //連線中先離開 } this.mreIsConnecting.Reset(); //先卡住, 不讓後面的再次進行 //若連線不曾建立, 或聆聽/連線被關閉 if (this.m_connSocket == null || !this.m_connSocket.Connected) { CtkNetUtil.DisposeSocketTry(this.m_connSocket); //Dispose舊的 this.m_connSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //建立新的 } if (this.IsActively) { if (this.LocalUri != null && !this.ConnSocket.IsBound) { this.ConnSocket.Bind(CtkNetUtil.ToIPEndPoint(this.LocalUri)); } if (this.RemoteUri == null) { throw new CtkException("remote field can not be null"); } this.ConnSocket.BeginConnect(CtkNetUtil.ToIPEndPoint(this.RemoteUri), new AsyncCallback(EndConnectCallback), this); } else { if (this.LocalUri == null) { throw new Exception("local field can not be null"); } if (!this.ConnSocket.IsBound) { this.ConnSocket.Bind(CtkNetUtil.ToIPEndPoint(this.LocalUri)); } this.ConnSocket.Listen(100); this.ConnSocket.BeginAccept(new AsyncCallback(EndAcceptCallback), this); } return(0); } catch (Exception ex) { //一旦聆聽/連線失敗, 直接關閉所有Socket, 重新來過 this.Disconnect(); this.OnFailConnect(new CtkProtocolEventArgs() { Message = "Connect Fail" }); throw ex;//同步型作業, 直接拋出例外, 不用寫Log } finally { if (Monitor.IsEntered(this)) { Monitor.Exit(this); } } }