public void Disconnect() { CtkUtil.DisposeTaskTry(this.runningTask); CtkNetUtil.DisposeTcpClientTry(this.MyTcpClient); this.OnDisconnect(new CtkNonStopTcpStateEventArgs() { Message = "Disconnect method is executed" }); }
public int ConnectTry() { try { if (!Monitor.TryEnter(this, 1000)) { return(-1); //進不去先離開 } if (!mreIsConnecting.WaitOne(10)) { return(0); //連線中就離開 } this.mreIsConnecting.Reset(); //先卡住, 不讓後面的再次進行連線 //在Lock後才判斷, 避免判斷無連線後, 另一邊卻連線好了 if (this.MyTcpClient != null && this.MyTcpClient.Connected) { return(0); //連線中直接離開 } if (this.MyTcpClient != null) { CtkNetUtil.DisposeTcpClientTry(this.MyTcpClient); this.MyTcpClient = null; } IPAddress ip = null; if (this.LocalUri != null && IPAddress.TryParse(this.LocalUri.Host, out ip)) { this.MyTcpClient = new TcpClient(new IPEndPoint(ip, this.LocalUri.Port)); } else { this.MyTcpClient = new TcpClient(); } this.MyTcpClient.NoDelay = true; this.MyTcpClient.Connect(this.RemoteUri.Host, this.RemoteUri.Port); return(0); } catch (Exception ex) { //停止連線 this.Disconnect(); throw ex; } finally { //同步作業, 最後要解除連線鎖 this.mreIsConnecting.Set(); if (Monitor.IsEntered(this)) { Monitor.Exit(this); } } }
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); } } }