public TCPIPServer() { state = new AsynReadState(BUFFER_SIZE); }
/// <summary> /// Asyn read result process /// </summary> /// <param name="ar"></param> private void OnDataRead(IAsyncResult ar) { int offset = 0; //used to keep the start position of a LLRP message in //byte array returned from the read AsynReadState ss = (AsynReadState)ar.AsyncState; //used to keep data int nReads = ns.EndRead(ar); //Detect client disconnection. then start anther acception if (ss.data[0] == 0) { server.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTCPClientCallBack), server); return; } lock (syn_msg) { try { REPEAT: if (new_message) //new_message is a flag to indicate if the data is part of unfinished message { msg_cursor = 0; int reserved_date_len = nReads - offset; if (reserved_date_len > 10) { //Calculate message type, version, length and id int header = (ss.data[offset] << 8) + ss.data[offset + 1]; try { msg_type = (Int16)(header & 0x03FF); msg_ver = (Int16)((header >> 10) & 0x07); msg_len = (ss.data[offset + 2] << 24) + (ss.data[offset + 3] << 16) + (ss.data[offset + 4] << 8) + ss.data[offset + 5]; msg_id = (ss.data[offset + 6] << 24) + (ss.data[offset + 7] << 16) + (ss.data[offset + 8] << 8) + ss.data[offset + 9]; } catch { msg_len = 0; } //if data length larger than needed data for a complete message, //copy data into existing message and triggered message event if (msg_len > 0 && msg_ver == 1) { msg_data = new byte[msg_len]; //if message length greater than the calcualted message length. copy message and trigger message event if (nReads >= (offset + msg_len)) { Array.Copy(ss.data, offset, msg_data, 0, msg_len); TriggerMessageEvent(msg_ver, msg_type, msg_id, msg_data); offset += msg_len; new_message = true; goto REPEAT; } else//If the received data is shorter than the message length, keep reading for the next data { new_message = false; Array.Copy(ss.data, offset, msg_data, 0, nReads - offset); msg_cursor = nReads - offset; } } } else { new_message = true; //if ns !=null, do next asyn-read, to ensure that read if (ns != null && ns.CanRead) { try { ns.Flush(); state = new AsynReadState(BUFFER_SIZE); Array.Copy(ss.data, offset, state.data, 0, reserved_date_len); if (!trying_to_close) { ns.BeginRead(state.data, reserved_date_len, BUFFER_SIZE - reserved_date_len, new AsyncCallback(OnDataRead), state); } } catch { } } return; } } else { //if data length larger than needed data for a complete message, //copy data into existing message and triggered message event if (nReads >= msg_len - msg_cursor) { Array.Copy(ss.data, 0, msg_data, msg_cursor, msg_len - msg_cursor); TriggerMessageEvent(msg_ver, msg_type, msg_id, msg_data); offset += msg_len - msg_cursor; new_message = true; goto REPEAT; } else //keep reading { new_message = false; Array.Copy(ss.data, 0, msg_data, msg_cursor, nReads); msg_cursor += nReads; } } //if ns !=null, do next asyn-read, to ensure that read if (ns != null && ns.CanRead) { try { ns.Flush(); state = new AsynReadState(BUFFER_SIZE); if (!trying_to_close) { ns.BeginRead(state.data, 0, BUFFER_SIZE, new AsyncCallback(OnDataRead), state); } } catch { } } } catch { } } }
private void OnDataRead(IAsyncResult ar) { int sourceIndex = 0; AsynReadState asyncState = (AsynReadState)ar.AsyncState; int length = this.ns.EndRead(ar); if (asyncState.data[0] == (byte)0) { this.server.BeginAcceptTcpClient(new AsyncCallback(this.DoAcceptTCPClientCallBack), (object)this.server); } else { lock (this.syn_msg) { try { int num1; while (true) { for (; !this.new_message; this.new_message = true) { if (length >= this.msg_len - this.msg_cursor) { Array.Copy((Array)asyncState.data, 0, (Array)this.msg_data, this.msg_cursor, this.msg_len - this.msg_cursor); this.TriggerMessageEvent(this.msg_ver, this.msg_type, this.msg_id, this.msg_data); sourceIndex += this.msg_len - this.msg_cursor; } else { this.new_message = false; Array.Copy((Array)asyncState.data, 0, (Array)this.msg_data, this.msg_cursor, length); this.msg_cursor += length; goto label_21; } } this.msg_cursor = 0; num1 = length - sourceIndex; if (num1 > 10) { int num2 = ((int)asyncState.data[sourceIndex] << 8) + (int)asyncState.data[sourceIndex + 1]; try { this.msg_type = (short)(num2 & 1023); this.msg_ver = (short)(num2 >> 10 & 7); this.msg_len = ((int)asyncState.data[sourceIndex + 2] << 24) + ((int)asyncState.data[sourceIndex + 3] << 16) + ((int)asyncState.data[sourceIndex + 4] << 8) + (int)asyncState.data[sourceIndex + 5]; this.msg_id = ((int)asyncState.data[sourceIndex + 6] << 24) + ((int)asyncState.data[sourceIndex + 7] << 16) + ((int)asyncState.data[sourceIndex + 8] << 8) + (int)asyncState.data[sourceIndex + 9]; } catch { this.msg_len = 0; } if (this.msg_len > 0 && this.msg_ver == (short)1) { this.msg_data = new byte[this.msg_len]; if (length >= sourceIndex + this.msg_len) { Array.Copy((Array)asyncState.data, sourceIndex, (Array)this.msg_data, 0, this.msg_len); this.TriggerMessageEvent(this.msg_ver, this.msg_type, this.msg_id, this.msg_data); sourceIndex += this.msg_len; this.new_message = true; } else { break; } } else { goto label_21; } } else { goto label_12; } } this.new_message = false; Array.Copy((Array)asyncState.data, sourceIndex, (Array)this.msg_data, 0, length - sourceIndex); this.msg_cursor = length - sourceIndex; goto label_21; label_12: this.new_message = true; if (this.ns == null) { return; } if (!this.ns.CanRead) { return; } try { this.ns.Flush(); this.state = new AsynReadState(1024); Array.Copy((Array)asyncState.data, sourceIndex, (Array)this.state.data, 0, num1); if (this.trying_to_close) { return; } this.ns.BeginRead(this.state.data, num1, 1024 - num1, new AsyncCallback(this.OnDataRead), (object)this.state); return; } catch { return; } label_21: if (this.ns == null) { return; } if (!this.ns.CanRead) { return; } try { this.ns.Flush(); this.state = new AsynReadState(1024); if (this.trying_to_close) { return; } this.ns.BeginRead(this.state.data, 0, 1024, new AsyncCallback(this.OnDataRead), (object)this.state); } catch { } } catch { } } } }