/// <summary> /// 開始讀取Socket資料, Begin 代表非同步. /// 用於 1. IsAutoRead被關閉, 每次讀取需自行執行; /// 2. 若連線還在, 但讀取異常中姒, 可以再度開始; /// </summary> public void BeginRead() { var myea = new CtkNonStopTcpStateEventArgs(); var client = this.ActiveWorkClient as TcpClient; myea.Sender = this; myea.WorkTcpClient = client; var trxBuffer = myea.TrxMessageBuffer; var stream = client.GetStream(); stream.BeginRead(trxBuffer.Buffer, 0, trxBuffer.Buffer.Length, new AsyncCallback(EndReadCallback), myea); }
/// <summary> /// Clinet Connect End /// </summary> /// <param name="ar"></param> void EndConnectCallback(IAsyncResult ar) { var myea = new CtkNonStopTcpStateEventArgs(); var trxBuffer = myea.TrxMessageBuffer; try { //Lock使用在短碼保護, 例如: 保護一個變數的get/set //Monitor使用在保護一段代碼 Monitor.Enter(this); //一定要等到進去 var state = (CtkTcpSocket)ar.AsyncState; state.WorkSocket = state.ConnSocket; //作為Client時, Work = Conn var client = state.WorkSocket; client.EndConnect(ar); myea.Sender = state; myea.WorkSocket = client; if (!ar.IsCompleted || client == null || !client.Connected) { throw new CtkException("Connection Fail"); } //呼叫他人不應影響自己運作, catch起來 try { this.OnFirstConnect(myea); } catch (Exception ex) { CtkLog.WarnNs(this, ex); } if (this.IsAsynAutoReceive) { client.BeginReceive(trxBuffer.Buffer, 0, trxBuffer.Buffer.Length, SocketFlags.None, new AsyncCallback(EndReceiveCallback), myea); } } //catch (SocketException ex) { } catch (Exception ex) { //失敗就中斷連線, 清除 this.Disconnect(); myea.Message = ex.Message; myea.Exception = ex; this.OnFailConnect(myea); CtkLog.WarnNs(this, ex); } finally { try { this.mreIsConnecting.Set(); /*同步型的, 結束就可以Set*/ } catch (ObjectDisposedException) { } Monitor.Exit(this); } }
void EndConnectCallback(IAsyncResult ar) { var myea = new CtkNonStopTcpStateEventArgs(); var trxBuffer = myea.TrxMessageBuffer; try { //Lock使用在短碼保護, 例如: 保護一個變數的get/set //Monitor使用在保護一段代碼 Monitor.Enter(this);//一定要等到進去 var state = (CtkTcpClient)ar.AsyncState; var client = state.MyTcpClient; client.EndConnect(ar); myea.Sender = state; myea.WorkTcpClient = client; if (!ar.IsCompleted || client.Client == null || !client.Connected) { throw new CtkException("Connection Fail"); } //呼叫他人不應影響自己運作, catch起來 try { this.OnFirstConnect(myea); } catch (Exception ex) { CtkLog.WarnNs(this, ex); } if (this.IsAsynAutoRead) { var stream = client.GetStream(); stream.BeginRead(trxBuffer.Buffer, 0, trxBuffer.Buffer.Length, new AsyncCallback(EndReadCallback), myea); } } //catch (SocketException ex) { } catch (Exception ex) { //失敗就中斷連線, 清除 this.Disconnect(); myea.Message = ex.Message; myea.Exception = ex; this.OnFailConnect(myea); CtkLog.WarnNs(this, ex); } finally { this.mreIsConnecting.Set(); Monitor.Exit(this); } }
/// <summary> /// 開始讀取Socket資料, Begin 代表非同步. /// 用於 1. IsAsynAutoReceive, 每次讀取需自行執行; /// 2. 若連線還在, 但讀取異常中止, 可以再度開始; /// </summary> public void BeginReceive() { var myea = new CtkNonStopTcpStateEventArgs(); //採用現正操作中的Socket進行接收 var client = this.ActiveWorkClient as Socket; myea.Sender = this; myea.WorkSocket = client; var trxBuffer = myea.TrxMessageBuffer; client.BeginReceive(trxBuffer.Buffer, 0, trxBuffer.Buffer.Length, SocketFlags.None, new AsyncCallback(EndReceiveCallback), myea); //EndReceive 是由 BeginReceive 回呼的函式中去執行 //也就是收到後, 通知結束工作的函式 //你無法在其它地方呼叫, 因為你沒有 IAsyncResult 的物件 }