/// <summary> /// Add the content of another writer to the writer /// </summary> /// <param name="value"></param> /// <remarks> /// This functionality is not allowed when the writer has been sealed /// </remarks> public void WriteBytes(ByteArrayWriter writer) { this.WriteBytes(((IByteArray)writer).Data); }
/// <summary> /// Running thread handler /// </summary> private void Worker() { //create a writer for the incoming data ByteArrayWriter writer = null; //loop, until the host closes while (this._closing == false) { //look for incoming data int length = this.Port.BytesToRead; if (length > 0) { var buffer = new byte[length]; //read the data from the physical port this.Port.Read( buffer, 0, length); //append the data to the writer if (writer == null) { writer = new ByteArrayWriter(); } writer.WriteBytes( buffer, 0, length); //try to decode the incoming data var data = new ServerCommData(this.Protocol); data.IncomingData = writer.ToReader(); CommResponse result = this.Protocol .Codec .ServerDecode(data); if (result.Status == CommResponse.Ack) { //the command is recognized, so call the host back this.OnServeCommand(data); //encode the host data this.Protocol .Codec .ServerEncode(data); //return the resulting data to the remote caller byte[] outgoing = data .OutgoingData .ToArray(); this.Port.Write( outgoing, 0, outgoing.Length); writer = null; } else if (result.Status == CommResponse.Ignore) { writer = null; } } Thread.Sleep(0); } }
/// <summary> /// Running thread handler /// </summary> protected override void Worker() { Debug.Print("start"); //start the local timer, which gets the session dying int counter = IdleTimeout; using (Timer timer = new Timer( _ => counter--, state: null, dueTime: 1000, period: 1000)) { //create a writer for the incoming data ByteArrayWriter writer = null; var buffer = new byte[CacheSize]; //loop, until the host closes, or the timer expires while ( this._closing == false && counter > 0) { //look for incoming data int length = this.Port.Available; if (length > 0) { if (length > CacheSize) { length = CacheSize; } //read the data from the physical port this.Port.Receive( buffer, length, SocketFlags.None); //append the data to the writer if (writer == null) { writer = new ByteArrayWriter(); } writer.WriteBytes( buffer, 0, length); //try to decode the incoming data var data = new ServerCommData(this.Protocol); data.IncomingData = writer.ToReader(); CommResponse result = this.Protocol .Codec .ServerDecode(data); if (result.Status == CommResponse.Ack) { //the command is recognized, so call the host back this.OnServeCommand(data); //encode the host data this.Protocol .Codec .ServerEncode(data); //return the resulting data to the remote caller byte[] outgoing = data .OutgoingData .ToArray(); this.Port.Send(outgoing); //reset the timer counter = IdleTimeout; writer = null; } else if (result.Status == CommResponse.Ignore) { writer = null; } } Thread.Sleep(0); } } this.Port.Close(); Debug.Print("close"); }
/// <summary> /// Entry-point for submitting a query to the remote device /// </summary> /// <param name="data"></param> /// <returns></returns> public CommResponse Query(ClientCommData data) { lock (this.Port) { //set the proper parameters to the port //this.Port.BaudRate = this.Setting.BaudRate; //this.Port.Parity = this.Setting.Parity; //this.Port.DataBits = this.Setting.DataBits; //this.Port.StopBits = this.Setting.StopBits; //convert the request data as an ordinary byte array byte[] outgoing = data .OutgoingData .ToArray(); //create a writer for accumulate the incoming data var incoming = new ByteArrayWriter(); const int tempSize = 64; var temp = new byte[tempSize]; //retries loop for (int attempt = 0, retries = data.Retries; attempt < retries; attempt++) { //flush any residual content this.Port .DiscardInBuffer(); this.Port .DiscardOutBuffer(); //phyiscal writing this.Port .Write(outgoing, 0, outgoing.Length); incoming.Reset(); //start the local timer bool timeoutExpired; int totalTimeout = this.Latency + data.Timeout; using (Timer timer = new Timer( _ => timeoutExpired = true, state: null, dueTime: totalTimeout, period: Timeout.Infinite)) { //reception loop, until a valid response or timeout timeoutExpired = false; while (timeoutExpired == false) { int length = this.Port.BytesToRead; if (length > 0) { if (length > tempSize) { length = tempSize; } //read the incoming data from the physical port this.Port .Read(temp, 0, length); //append data to the writer incoming.WriteBytes( temp, 0, length); //try to decode the stream data.IncomingData = incoming.ToReader(); CommResponse result = data .OwnerProtocol .Codec .ClientDecode(data); //exit whether any concrete result: either good or bad if (result.Status == CommResponse.Ack) { return(result); } else if (result.Status == CommResponse.Critical) { return(result); } else if (result.Status != CommResponse.Unknown) { break; } } Thread.Sleep(0); //stop immediately if the host asked to abort //TODO } } //using (timer) } //for //no attempt was successful return(new CommResponse( data, CommResponse.Critical)); } //lock }