GPSsockets通信(CONCOX)

1 ] 1我有一个gps设备应该发送GPRMC数据,但它需要登录packect查看dataSheet 设备数据表

在此处输入图像描述

我可以收到登录信息787811010 XXX739050313XXX 20200001000E0EAD0D0A

IMEI Sart With XXX 

数据包与示例图像不同

我有2个问题1 – 根据数据recieveid和示例应该发送什么2-如何钙化错误检查谢谢

编辑

 public static void StartListening() { // Data buffer for incoming data. byte[] bytes = new Byte[1024]; // Establish the local endpoint for the socket. // The DNS name of the computer // running the listener is "host.contoso.com". IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress = ipHostInfo.AddressList[0]; IPAddress local = IPAddress.Parse("My IP"); IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 8841); // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Bind the socket to the local endpoint and listen for incoming connections. try { listener.Bind(localEndPoint); listener.Listen(100); while (true) { // Set the event to nonsignaled state. allDone.Reset(); // Start an asynchronous socket to listen for connections. // Console.WriteLine("Waiting for a connection..."); listener.BeginAccept( new AsyncCallback(AcceptCallback), listener); // Wait until a connection is made before continuing. allDone.WaitOne(); } } catch (Exception e) { // Console.WriteLine(e.ToString()); } // Console.WriteLine("\nPress ENTER to continue..."); // Console.Read(); } private static void Send(Socket handler, String data) { // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); } private static void Send(Socket handler, byte[] data) { // Convert the string data to byte data using ASCII encoding. // byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), handler); } private static void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket handler = (Socket)ar.AsyncState; // Complete sending the data to the remote device. int bytesSent = handler.EndSend(ar); // Console.WriteLine("Sent {0} bytes to client.", bytesSent); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (Exception e) { // Console.WriteLine(e.ToString()); } } public static void AcceptCallback(IAsyncResult ar) { // Signal the main thread to continue. allDone.Set(); // Get the socket that handles the client request. Socket listener = (Socket)ar.AsyncState; Socket handler = listener.EndAccept(ar); // Create the state object. StateObject state = new StateObject(); state.workSocket = handler; handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } static byte[] Unpack(string data) { //return null indicates an error List bytes = new List(); // check start and end bytes if ((data.Substring(0, 4) != "7878") && (data.Substring(data.Length - 4) != "0D0A")) { return null; } for (int index = 4; index < data.Length - 4; index += 2) { bytes.Add(byte.Parse(data.Substring(index, 2), System.Globalization.NumberStyles.HexNumber)); } //crc test byte[] packet = bytes.Take(bytes.Count - 2).ToArray(); byte[] crc = bytes.Skip(bytes.Count - 2).ToArray(); uint CalculatedCRC = crc_bytes(packet); return packet; } public static UInt16 crc_bytes(byte[] data) { ushort crc = 0xFFFF; for (int i = 0; i < data.Length; i++) { crc ^= (ushort)(data[i] << 8); for (int j = 0; j  0) crc = (ushort)((crc << 1) ^ 0x1021); else crc < 0) { if (state.buffer[3] == 1) { string input = BitConverter.ToString(state.buffer, 0, bytesRead).Replace("-", ""); byte[] bytes = Unpack(input); byte[] serialNumber = bytes.Skip(bytes.Length - 2).ToArray(); byte[] response = { 0x78, 0x78, 0x05, 0x01, 0x00, 0x00, 0x00, 0x0 }; serialNumber.CopyTo(response, 4); UInt16 sendCRC = crc_bytes(response.Take(response.Length - 2).ToArray()); response[response.Length - 2] = (byte)((sendCRC >> 8) & 0xFF); response[response.Length - 1] = (byte)((sendCRC) & 0xFF); Send(handler, response); // handler.Send(response); } else { // There might be more data, so store the data received so far. state.sb.Append(Encoding.ASCII.GetString( state.buffer, 0, bytesRead)); // Check for end-of-file tag. If it is not there, read // more data. content = state.sb.ToString(); SaveData(content); // Not all data received. Get more. handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); // } } } } 

供应商数据表

4.6。 错误检查终端或服务器可以使用检查代码来区分接收的信息是否错误。 为了防止数据传输过程中出现错误,增加了错误检查以防止数据误操作,从而提高系统的安全性和效率。 校验码由CRC-ITU检查方法生成。 从分组长度到信息序列号(包括“分组长度”和“信息序列号”)的协议结构中的数据的校验码是CRC-ITU的值。 当计算接收信息时发生CRC错误,接收器将忽略并丢弃数据包。 4

数据库表

 CREATE TABLE [dbo].[T_Tracking]( [id] [int] IDENTITY(1,1) NOT NULL, [IMEI] [nvarchar](50) NULL, [TrackTime] [datetime] NULL, [CurrTime] [datetime] NULL CONSTRAINT [DF_T_Tracking_CurrTime] DEFAULT (getutcdate()), [Longitude] [nvarchar](50) NULL, [Lattitude] [nvarchar](50) NULL, [speed] [float] NULL 

你代码

  switch (protocolNumber) { case PROTOCOL_NUMBER.LOGIN_MESSAGE: serialNumber.CopyTo(loginResponse, 4); sendCRC = crc_bytes(loginResponse.Skip(2).Take(loginResponse.Length - 6).ToArray()); loginResponse[loginResponse.Length - 4] = (byte)((sendCRC >> 8) & 0xFF); loginResponse[loginResponse.Length - 3] = (byte)((sendCRC) & 0xFF); string terminalID = Encoding.ASCII.GetString(receiveMessage.Skip(4).Take(messageLength - 5).ToArray()); Console.WriteLine("Received good login message from Serial Number : '{0}', Terminal ID = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), terminalID); Console.WriteLine("Send Message : '{0}'", BytesToString(loginResponse)); Send(state.workSocket, loginResponse); break; case PROTOCOL_NUMBER.LOCATION_DATA: year = receiveMessage[4]; month = receiveMessage[5]; day = receiveMessage[6]; hour = receiveMessage[7]; minute = receiveMessage[8]; second = receiveMessage[9]; date = new DateTime(2000 + year, month, day, hour, minute, second); Console.WriteLine("Received good location message from Serial Number '{0}', Time = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), date.ToLongDateString()); string lng = message.Substring(22, 8); Int64 lngVal = Convert.ToInt64(lng, 16); double step3 = (double)lngVal / 30000; double step4 = (double)((step3 / 60)); //int lngdeg =Convert.ToInt32( step4.ToString().Split('.')[0]); // double step5 = (double)(step4 * 60) - step3; string lat = message.Substring(30, 8); Int64 altVal = Convert.ToInt64(lat, 16); double Lstep3 = (double)altVal / 30000; double Lstep4 = (double)((Lstep3) / 60); // double Lstep5 = (double)(Lstep4 * 60) - Lstep3; //Console.WriteLine("Date : '{0}',Long : '{1}', Receive Message : '{2}'", dateStr, step4, Lstep4); string speedstr = message.Substring(38, 2); int SpeedVal = Convert.ToInt32(speedstr, 16); SaveData(IMEI , dateStr, step4.ToString(), Lstep4.ToString(), SpeedVal);//Get IMEI From Login Message that is the Problem break; 

在此处输入图像描述

状态消息 在此处输入图像描述

这是第2节:

  public void ProcessMessages() { UInt16 sendCRC = 0; DateTime date; int year = 0; int month = 0; int day = 0; int hour = 0; int minute = 0; int second = 0; KeyValuePair, StateObject> byteState; KeyValuePair status; byte[] receiveMessage = null; StateObject state = null; byte[] serialNumber = null; byte[] serverFlagBit = null; byte[] stringArray = null; string stringMessage = ""; byte lengthOfCommand = 0; PROTOCOL_NUMBER protocolNumber = PROTOCOL_NUMBER.NONE; try { Boolean firstMessage = true; acceptDone.Set(); //loop forever while (true) { allDone.WaitOne(); //read fifo until empty while (true) { //read one connection until buffer doesn't contain any more packets byteState = ReadWrite(PROCESS_STATE.PROCESS, null, null, -1); if (byteState.Value.fifoCount == -1) break; state = byteState.Value; while (true) { status = Unpack(byteState); if (status.Key == UNPACK_STATUS.NOT_ENOUGH_BYTES) break; if (status.Key == UNPACK_STATUS.ERROR) { Console.WriteLine("Error : Bad Receive Message, Data"); break; } //message is 2 start bytes + 1 byte (message length) + 1 byte message length + 2 end bytes receiveMessage = status.Value; int messageLength = receiveMessage[2]; Console.WriteLine("Status : '{0}', Receive Message : '{1}'", status.Key == UNPACK_STATUS.GOOD_MESSAGE ? "Good" : "Bad", BytesToString(receiveMessage.Take(messageLength + 5).ToArray())); if (status.Key != UNPACK_STATUS.GOOD_MESSAGE) { break; } else { if (firstMessage) { if (receiveMessage[3] != 0x01) { Console.WriteLine("Error : Expected Login Message : '{0}'", BytesToString(receiveMessage)); break; } firstMessage = false; } //skip start bytes, message length. then go back 4 bytes (CRC and serial number) serialNumber = receiveMessage.Skip(2 + 1 + messageLength - 4).Take(2).ToArray(); protocolNumber = (PROTOCOL_NUMBER)receiveMessage[3]; Console.WriteLine("Protocol Number : '{0}'",protocolNumber.ToString()); switch (protocolNumber) { case PROTOCOL_NUMBER.LOGIN_MESSAGE: serialNumber.CopyTo(loginResponse, 4); sendCRC = crc_bytes(loginResponse.Skip(2).Take(loginResponse.Length - 6).ToArray()); loginResponse[loginResponse.Length - 4] = (byte)((sendCRC >> 8) & 0xFF); loginResponse[loginResponse.Length - 3] = (byte)((sendCRC) & 0xFF); // string IMEI = Encoding.ASCII.GetString(receiveMessage.Skip(4).Take(messageLength - 5).ToArray()); byteState.Value.IMEI = IMEI; Console.WriteLine("Received good login message from Serial Number : '{0}', Terminal ID = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), IMEI); Console.WriteLine("Send Message : '{0}'", BytesToString(loginResponse)); Send(state.workSocket, loginResponse); WriteDBMessageLogin loginMessage = new WriteDBMessageLogin() { message = DATABASE_MESSAGE_TYPE.LOGIN, IMEI = IMEI, date = DateTime.Now }; WriteDBAsync.ReadWriteFifo(WriteDBAsync.Mode.WRITE, loginMessage); Console.WriteLine("Wrote to database"); break; case PROTOCOL_NUMBER.LOCATION_DATA: year = receiveMessage[4]; month = receiveMessage[5]; day = receiveMessage[6]; hour = receiveMessage[7]; minute = receiveMessage[8]; second = receiveMessage[9]; date = new DateTime(2000 + year, month, day, hour, minute, second); WriteDBMessageLocation locationMessage = new WriteDBMessageLocation(); locationMessage.message = DATABASE_MESSAGE_TYPE.LOCATION; locationMessage.trackTime = date; locationMessage.currTime = DateTime.Now; locationMessage.lattitude = new byte[4]; Array.Copy(receiveMessage, 11, locationMessage.lattitude, 0, 4); locationMessage.longitude = new byte[4]; Array.Copy(receiveMessage, 15, locationMessage.longitude, 0, 4); locationMessage.speed = receiveMessage[19]; locationMessage.courseStatus = new byte[2]; Array.Copy(receiveMessage, 20, locationMessage.courseStatus, 0, 2); locationMessage.IMEI = byteState.Value.IMEI; WriteDBAsync.ReadWriteFifo(WriteDBAsync.Mode.WRITE, locationMessage); Console.WriteLine("Received good location message from Serial Number '{0}', Time = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), date.ToLongDateString()); break; case PROTOCOL_NUMBER.ALARM_DATA: //first response int alarmPacketLen = alarmResponse.Length - 5; alarmResponse[2] = (byte)(alarmPacketLen & 0xFF); serialNumber.CopyTo(alarmResponse, alarmPacketLen - 1); sendCRC = crc_bytes(alarmResponse.Skip(2).Take(alarmPacketLen - 1).ToArray()); alarmResponse[alarmPacketLen + 1] = (byte)((sendCRC >> 8) & 0xFF); alarmResponse[alarmPacketLen + 2] = (byte)((sendCRC) & 0xFF); Console.WriteLine("Send Alarm Response Message : '{0}'", BytesToString(alarmResponse)); Send(state.workSocket, alarmResponse); //second response year = receiveMessage[4]; month = receiveMessage[5]; day = receiveMessage[6]; hour = receiveMessage[7]; minute = receiveMessage[8]; second = receiveMessage[9]; date = new DateTime(2000 + year, month, day, hour, minute, second); Console.WriteLine("Received good alarm message from Serial Number '{0}', Time = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), date.ToLongDateString()); int alarmDataAddressPacketLen = alarmDataAddressResponse.Length - 5; alarmDataAddressResponse[2] = (byte)(alarmDataAddressPacketLen & 0xFF); serialNumber.CopyTo(alarmDataAddressResponse, alarmDataAddressPacketLen - 1); sendCRC = crc_bytes(alarmDataAddressResponse.Skip(2).Take(alarmDataAddressPacketLen - 1).ToArray()); alarmDataAddressResponse[alarmDataAddressPacketLen + 1] = (byte)((sendCRC >> 8) & 0xFF); alarmDataAddressResponse[alarmDataAddressPacketLen + 2] = (byte)((sendCRC) & 0xFF); Console.WriteLine("Send Alarm Data Address Message : '{0}'", BytesToString(alarmDataAddressResponse)); Send(state.workSocket, alarmDataAddressResponse); break; case PROTOCOL_NUMBER.STATUS_INFO: serialNumber.CopyTo(heartbeatResponse, 4); byte info = receiveMessage[4]; byte voltage = receiveMessage[5]; byte GSMsignalStrength = receiveMessage[6]; UInt16 alarmLanguage = (UInt16)((receiveMessage[7] << 8) | receiveMessage[8]); ALARM alarm = (ALARM)((info >> 3) & 0x07); sendCRC = crc_bytes(heartbeatResponse.Skip(2).Take(heartbeatResponse.Length - 6).ToArray()); heartbeatResponse[heartbeatResponse.Length - 4] = (byte)((sendCRC >> 8) & 0xFF); heartbeatResponse[heartbeatResponse.Length - 3] = (byte)((sendCRC) & 0xFF); Console.WriteLine("Received good status message from Serial Number : '{0}', INFO : '0x{1}{2}{3}{4}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), info.ToString("X2"), voltage.ToString("X2"), GSMsignalStrength.ToString("X2"), alarmLanguage.ToString("X4")); Console.WriteLine("Send Message : '{0}'", BytesToString(heartbeatResponse)); Send(state.workSocket, heartbeatResponse); switch (alarm) { //reset cut off alarm case ALARM.POWER_CUT_ALARM: int connectOilAndElectricityPacketLen = connectOilAndEletricity.Length - 5; serialNumber.CopyTo(connectOilAndEletricity, connectOilAndElectricityPacketLen - 1); sendCRC = crc_bytes(connectOilAndEletricity.Skip(2).Take(connectOilAndEletricity.Length - 6).ToArray()); connectOilAndEletricity[connectOilAndEletricity.Length - 4] = (byte)((sendCRC >> 8) & 0xFF); connectOilAndEletricity[connectOilAndEletricity.Length - 3] = (byte)((sendCRC) & 0xFF); serverFlagBit = new byte[4]; Array.Copy(connectOilAndEletricity, 5, serverFlagBit, 0, 4); lengthOfCommand = connectOilAndEletricity[4]; stringArray = new byte[lengthOfCommand - 4]; //do not include server flag bit Array.Copy(connectOilAndEletricity, 9, stringArray, 0, lengthOfCommand - 4); stringMessage = Encoding.ASCII.GetString(stringArray); Console.WriteLine("Reset Oil and Electricity, Server Flag Bit : '{0}{1}{2}{3}', Message : '{4}'", serverFlagBit[0].ToString("X2"), serverFlagBit[1].ToString("X2"), serverFlagBit[2].ToString("X2"), serverFlagBit[3].ToString("X2"), stringMessage); Send(state.workSocket, connectOilAndEletricity); break; } break; case PROTOCOL_NUMBER.STRING_INFO : lengthOfCommand = receiveMessage[4]; serverFlagBit = new byte[4]; Array.Copy(receiveMessage, 5, serverFlagBit, 0, 4); stringArray = new byte[lengthOfCommand - 4]; //do not include server flag bit Array.Copy(receiveMessage, 9, stringArray, 0, lengthOfCommand - 4); stringMessage = Encoding.ASCII.GetString(stringArray); Console.WriteLine("String Message, Server Flag Bit : '{0}{1}{2}{3}', Message : '{4}'", serverFlagBit[0].ToString("X2"), serverFlagBit[1].ToString("X2"), serverFlagBit[2].ToString("X2"), serverFlagBit[3].ToString("X2"), stringMessage); break; } //end switch }// End if } //end while }//end while fifo > 0 allDone.Reset(); }//end while true } catch (Exception e) { Console.WriteLine(e.Message); } } static string BytesToString(byte[] bytes) { return string.Join("", bytes.Select(x => x.ToString("X2"))); } static KeyValuePair Unpack(KeyValuePair, StateObject> bitState) { List working_buffer = bitState.Key; //return null indicates an error if (working_buffer.Count() < 3) return new KeyValuePair(UNPACK_STATUS.NOT_ENOUGH_BYTES, null); int len = working_buffer[2]; if (working_buffer.Count < len + 5) return new KeyValuePair(UNPACK_STATUS.NOT_ENOUGH_BYTES, null); // check start and end bytes // remove message fro workig buffer and dictionary KeyValuePair, StateObject> byteState = ReadWrite(PROCESS_STATE.UNPACK, null, null, bitState.Value.connectionNumber); if (byteState.Key.Count == 0) return new KeyValuePair(UNPACK_STATUS.ERROR, null); List packet = byteState.Key; //crc test byte[] crc = packet.Skip(len + 1).Take(2).ToArray(); ushort crcShort = (ushort)((crc[0] << 8) | crc[1]); //skip start bytes, crc, and end bytes ushort CalculatedCRC = crc_bytes(packet.Skip(2).Take(len - 1).ToArray()); if (CalculatedCRC != crcShort) { return new KeyValuePair(UNPACK_STATUS.BAD_CRC, packet.ToArray()); } return new KeyValuePair(UNPACK_STATUS.GOOD_MESSAGE, packet.ToArray()); } static public UInt16 crc_bytes(byte[] data) { ushort crc = 0xFFFF; for (int i = 0; i < data.Length; i++) { crc ^= (ushort)(Reflect(data[i], 8) << 8); for (int j = 0; j < 8; j++) { if ((crc & 0x8000) > 0) crc = (ushort)((crc << 1) ^ 0x1021); else crc <<= 1; } } crc = Reflect(crc, 16); crc = (ushort)~crc; return crc; } static public ushort Reflect(ushort data, int size) { ushort output = 0; for (int i = 0; i < size; i++) { int lsb = data & 0x01; output = (ushort)((output << 1) | lsb); data >>= 1; } return output; } static KeyValuePair, StateObject> ReadWrite(PROCESS_STATE ps, Socket handler, IAsyncResult ar, long unpackConnectionNumber) { KeyValuePair, StateObject> byteState = new KeyValuePair, StateObject>(); ; StateObject stateObject = null; int bytesRead = -1; int workingBufferLen = 0; List working_buffer = null; byte[] buffer = null; Object thisLock1 = new Object(); lock (thisLock1) { switch (ps) { case PROCESS_STATE.ACCEPT: acceptDone.WaitOne(); acceptDone.Reset(); stateObject = new StateObject(); stateObject.buffer = new byte[BUFFER_SIZE]; connectionDict.Add(connectionNumber, new KeyValuePair, StateObject>(new List(), stateObject)); stateObject.connectionNumber = connectionNumber++; stateObject.workSocket = handler; byteState = new KeyValuePair, StateObject>(null, stateObject); acceptDone.Set(); break; case PROCESS_STATE.READ: //catch when client disconnects //wait if accept is being called //acceptDone.WaitOne(); try { stateObject = ar.AsyncState as StateObject; // Read data from the client socket. bytesRead = stateObject.workSocket.EndReceive(ar); if (bytesRead > 0) { byteState = connectionDict[stateObject.connectionNumber]; buffer = new byte[bytesRead]; Array.Copy(byteState.Value.buffer, buffer, bytesRead); byteState.Key.AddRange(buffer); } //only put one instance of connection number into fifo if (!fifo.Contains(byteState.Value.connectionNumber)) { fifo.Add(byteState.Value.connectionNumber); } } catch (Exception ex) { //will get here if client disconnects fifo.RemoveAll(x => x == byteState.Value.connectionNumber); connectionDict.Remove(byteState.Value.connectionNumber); byteState = new KeyValuePair, StateObject>(new List(), null); } break; case PROCESS_STATE.PROCESS: if (fifo.Count > 0) { //get message from working buffer //unpack will later delete message //remove connection number from fifo // the list in the key in known as the working buffer byteState = new KeyValuePair, StateObject>(connectionDict[fifo[0]].Key, connectionDict[fifo[0]].Value); fifo.RemoveAt(0); //put a valid value in fifoCount so -1 below can be detected. byteState.Value.fifoCount = fifo.Count; } else { //getting here is normal when there is no more work to be performed //set fifocount to zero so rest of code know fifo was empty so code waits for next receive message byteState = new KeyValuePair, StateObject>(null, new StateObject() { fifoCount = -1 }); } break; case PROCESS_STATE.UNPACK: try { working_buffer = connectionDict[unpackConnectionNumber].Key; workingBufferLen = working_buffer[2]; if ((working_buffer[0] != 0x78) && (working_buffer[1] != 0x78) && (working_buffer[workingBufferLen + 3] != 0x0D) && (working_buffer[workingBufferLen + 4] != 0x0A)) { working_buffer.Clear(); return new KeyValuePair, StateObject>(new List(), null); } List packet = working_buffer.GetRange(0, workingBufferLen + 5); working_buffer.RemoveRange(0, workingBufferLen + 5); byteState = new KeyValuePair, StateObject>(packet, null); } catch(Exception ex) { int testPoint = 0; } break; }// end switch } return byteState; } static void Send(Socket handler, String data) { // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); } static void Send(Socket socket, byte[] data) { // Convert the string data to byte data using ASCII encoding. // byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. socket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), socket); } static void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket handler = ar.AsyncState as Socket; // Complete sending the data to the remote device. int bytesSent = handler.EndSend(ar); // Console.WriteLine("Sent {0} bytes to client.", bytesSent); } catch (Exception e) { // Console.WriteLine(e.ToString()); int myerror = -1; } } public static void AcceptCallback(IAsyncResult ar) { try { // Get the socket that handles the client request. // Retrieve the state object and the handler socket // from the asynchronous state object. Socket listener = (Socket)ar.AsyncState; Socket handler = listener.EndAccept(ar); // Create the state object. StateObject state = ReadWrite(PROCESS_STATE.ACCEPT, handler, ar, - 1).Value; handler.BeginReceive(state.buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(ReadCallback), state); } catch (Exception ex) { int myerror = -1; } } public static void ReadCallback(IAsyncResult ar) { try { StateObject state = ar.AsyncState as StateObject; Socket handler = state.workSocket; // Read data from the client socket. KeyValuePair, StateObject> byteState = ReadWrite(PROCESS_STATE.READ, handler, ar, -1); if (byteState.Value != null) { allDone.Set(); handler.BeginReceive(state.buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(ReadCallback), state); } else { int testPoint = 0; } } catch (Exception ex) { int myerror = -1; } // Signal the main thread to continue. allDone.Set(); } } } 

请尝试以下代码。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; using System.Data; using System.Data.SqlClient; using System.ComponentModel; using System.Timers; namespace ConcoxServer { public class StateObject { public long connectionNumber = -1; public Socket workSocket { get; set; } public byte[] buffer { get; set; } public int fifoCount { get; set; } } public class StateObjectDB { public string terminalID { get; set; } public DateTime date { get; set; } } public enum PROTOCOL_NUMBER { LOGIN_MESSAGE = 0x01, LOCATION_DATA = 0x12, STATUS_INFO = 0X13, STRING_INFO = 0X15, ALARM_DATA = 0X16, GPS_QUERY_ADDR_PHONE_NUM = 0X1A, COMMAND_INFO = 0X80, NONE } public enum UNPACK_STATUS { ERROR, NOT_ENOUGH_BYTES, BAD_CRC, GOOD_MESSAGE, DEFAULT } public enum PROCESS_STATE { ACCEPT, READ, PROCESS, UNPACK } class Program { const string IP = "127.0.0.1"; const int PORT = 8841; const Boolean test = true; static void Main(string[] args) { GPS gps = new GPS(IP, PORT, test); Console.WriteLine("Connection Ended"); } } public class GPS { const int BUFFER_SIZE = 1024; const string CONNECT_STRING = @"Data Source=.\SQLEXPRESS;Initial Catalog=GPSTracker;Integrated Security=SSPI;"; const string LOGIN_INSERT_COMMMAND_TEXT = "use GPSTracker INSERT INTO Login (TerminalID,Date) VALUES(@TerminalID,@Date)"; static SqlConnection conn = null; static SqlCommand cmd = null; static byte[] loginResponse = { 0x78, 0x78, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A }; static byte[] alarmResponse = { 0x78, 0x78, 0x00, 0x97, 0x7E, 0x00, 0x00, 0x00, 0x01, 0x41, 0x4C, 0x41, 0x52, 0x4D, 0x53, 0x4D, 0x53, //ALARMS 0x26, 0x26, //&& 0x80, 0x00, 0x72, 0x00, 0x79, 0x00, 0x78, 0x00, // PHONE HOME 0x69, 0x00, 0x32, 0x00, 0x72, 0x00, 0x79, 0x00, 0x77, 0x00, 0x69, 0x26, 0x26, //&& 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Phone Numbe 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x23, //## 0x00, 0x00, //serial number 0x00, 0x00, //check bytes 0x0D, 0x0A //stop bytes }; static long connectionNumber = 0; //mapping of connection number to StateObject static Dictionary, StateObject>> connectionDict = new Dictionary, StateObject>>(); //fifo contains list of connections number wait with receive data public static List fifo = new List(); public static AutoResetEvent allDone = new AutoResetEvent(false); public static AutoResetEvent acceptDone = new AutoResetEvent(false); public GPS(string IP, int port, Boolean test) { try { conn = new SqlConnection(CONNECT_STRING); conn.Open(); cmd = new SqlCommand(LOGIN_INSERT_COMMMAND_TEXT, conn); cmd.Parameters.Add("@TerminalID", SqlDbType.NVarChar, 8); cmd.Parameters.Add("@Date", SqlDbType.DateTime); } catch (Exception ex) { Console.WriteLine("Error : '{0}'", ex.Message); //Console.ReadLine(); return; } try { //initialize the timer for writing to database. WriteDBAsync.WriteDatabase(); StartListening(IP, port, test); // Open 2nd listener to simulate two devices, Only for testing //StartListening(IP, port + 1, test); ProcessMessages(); } catch (Exception ex) { Console.WriteLine("Error : '{0}'", ex.Message); //Console.ReadLine(); return; } } public static class WriteDBAsync { public enum Mode { READ, WRITE } public static List> fifo = new List>(); public static System.Timers.Timer timer = null; public static void WriteDatabase() { timer = new System.Timers.Timer(100); timer.Elapsed += Timer_Elapsed; timer.Start(); } public static List ReadWriteFifo(Mode mode, StateObjectDB stateObjectDB) { List row = null; Object thisLock2 = new Object(); lock (thisLock2) { switch (mode) { case Mode.READ: if (fifo.Count > 0) { row = fifo[0]; fifo.RemoveAt(0); } break; case Mode.WRITE: row = new List() { stateObjectDB.terminalID, stateObjectDB.date }; fifo.Add(row); break; } } return row; } static void Timer_Elapsed(object sender, ElapsedEventArgs e) { timer.Enabled = false; List row = null; try { while ((row = ReadWriteFifo(Mode.READ, null)) != null) { cmd.Parameters["@TerminalID"].Value = row[0]; cmd.Parameters["@Date"].Value = row[1]; int rowsAdded = cmd.ExecuteNonQuery(); } } catch (Exception ex) { //Console.WriteLine("Error : '{0}'", ex.Message); } timer.Enabled = true; } } public void StartListening(string IP, int port, Boolean test) { try { // Establish the local endpoint for the socket. // The DNS name of the computer // running the listener is "host.contoso.com". IPHostEntry ipHostInfo = Dns.GetHostEntry(IP); //Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress = ipHostInfo.AddressList[0]; //IPAddress local = IPAddress.Parse(IP); IPEndPoint localEndPoint = null; if (test) { localEndPoint = new IPEndPoint(IPAddress.Any, port); } else { localEndPoint = new IPEndPoint(ipAddress, port); } // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Bind the socket to the local endpoint and listen for incoming connections. allDone.Reset(); acceptDone.Reset(); listener.Bind(localEndPoint); listener.Listen(100); //login code, wait for 1st message Console.WriteLine("Wait 5 seconds for login message"); listener.BeginAccept(new AsyncCallback(AcceptCallback), listener); } catch (Exception e) { Console.WriteLine(e.Message); } } public void ProcessMessages() { UInt16 sendCRC = 0; DateTime date; int year = 0; int month = 0; int day = 0; int hour = 0; int minute = 0; int second = 0; KeyValuePair, StateObject> byteState; KeyValuePair status; byte[] receiveMessage = null; StateObject state = null; byte[] serialNumber = null; PROTOCOL_NUMBER protocolNumber = PROTOCOL_NUMBER.NONE; try { Boolean firstMessage = true; acceptDone.Set(); //loop forever while (true) { allDone.WaitOne(); //read fifo until empty while (true) { //read one connection until buffer doesn't contain any more packets byteState = ReadWrite(PROCESS_STATE.PROCESS, null, null, -1); if (byteState.Value.fifoCount == -1) break; state = byteState.Value; while (true) { status = Unpack(byteState); if (status.Key == UNPACK_STATUS.NOT_ENOUGH_BYTES) break; if (status.Key == UNPACK_STATUS.ERROR) { Console.WriteLine("Error : Bad Receive Message, Data"); break; } //message is 2 start bytes + 1 byte (message length) + 1 byte message length + 2 end bytes receiveMessage = status.Value; int messageLength = receiveMessage[2]; Console.WriteLine("Status : '{0}', Receive Message : '{1}'", status.Key == UNPACK_STATUS.GOOD_MESSAGE ? "Good" : "Bad", BytesToString(receiveMessage.Take(messageLength + 5).ToArray())); if (status.Key != UNPACK_STATUS.GOOD_MESSAGE) { break; } else { if (firstMessage) { if (receiveMessage[3] != 0x01) { Console.WriteLine("Error : Expected Login Message : '{0}'", BytesToString(receiveMessage)); break; } firstMessage = false; } //skip start bytes, message length. then go back 4 bytes (CRC and serial number) serialNumber = receiveMessage.Skip(2 + 1 + messageLength - 4).Take(2).ToArray(); protocolNumber = (PROTOCOL_NUMBER)receiveMessage[3]; Console.WriteLine("Protocol Number : '{0}'", protocolNumber.ToString()); switch (protocolNumber) { case PROTOCOL_NUMBER.LOGIN_MESSAGE: serialNumber.CopyTo(loginResponse, 4); sendCRC = crc_bytes(loginResponse.Skip(2).Take(loginResponse.Length - 6).ToArray()); loginResponse[loginResponse.Length - 4] = (byte)((sendCRC >> 8) & 0xFF); loginResponse[loginResponse.Length - 3] = (byte)((sendCRC) & 0xFF); // string terminalID = Encoding.ASCII.GetString(receiveMessage.Skip(4).Take(messageLength - 5).ToArray()); Console.WriteLine("Received good login message from Serial Number : '{0}', Terminal ID = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), terminalID); Console.WriteLine("Send Message : '{0}'", BytesToString(loginResponse)); Send(state.workSocket, loginResponse); StateObjectDB stateObjectDB = new StateObjectDB() { terminalID = terminalID, date = DateTime.Now }; WriteDBAsync.ReadWriteFifo(WriteDBAsync.Mode.WRITE, stateObjectDB); Console.WriteLine("Wrote to database"); break; case PROTOCOL_NUMBER.LOCATION_DATA: year = receiveMessage[4]; month = receiveMessage[5]; day = receiveMessage[6]; hour = receiveMessage[7]; minute = receiveMessage[8]; second = receiveMessage[9]; date = new DateTime(2000 + year, month, day, hour, minute, second); Console.WriteLine("Received good location message from Serial Number '{0}', Time = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), date.ToLongDateString()); break; case PROTOCOL_NUMBER.ALARM_DATA: year = receiveMessage[4]; month = receiveMessage[5]; day = receiveMessage[6]; hour = receiveMessage[7]; minute = receiveMessage[8]; second = receiveMessage[9]; date = new DateTime(2000 + year, month, day, hour, minute, second); Console.WriteLine("Received good alarm message from Serial Number '{0}', Time = '{1}'", "0x" + serialNumber[0].ToString("X2") + serialNumber[1].ToString("X2"), date.ToLongDateString()); int packetLen = alarmResponse.Length - 5; alarmResponse[2] = (byte)(packetLen & 0xFF); serialNumber.CopyTo(alarmResponse, packetLen - 1); sendCRC = crc_bytes(alarmResponse.Skip(2).Take(packetLen - 1).ToArray()); alarmResponse[packetLen + 1] = (byte)((sendCRC >> 8) & 0xFF); alarmResponse[packetLen + 2] = (byte)((sendCRC) & 0xFF); Console.WriteLine("Send Message : '{0}'", BytesToString(alarmResponse)); Send(state.workSocket, alarmResponse); break; } //end switch }// End if } //end while }//end while fifo > 0 allDone.Reset(); }//end while true } catch (Exception e) { Console.WriteLine(e.Message); } } static string BytesToString(byte[] bytes) { return string.Join("", bytes.Select(x => x.ToString("X2"))); } static KeyValuePair Unpack(KeyValuePair, StateObject> bitState) { List working_buffer = bitState.Key; //return null indicates an error if (working_buffer.Count() < 3) return new KeyValuePair(UNPACK_STATUS.NOT_ENOUGH_BYTES, null); int len = working_buffer[2]; if (working_buffer.Count < len + 5) return new KeyValuePair(UNPACK_STATUS.NOT_ENOUGH_BYTES, null); // check start and end bytes // remove message fro workig buffer and dictionary KeyValuePair, StateObject> byteState = ReadWrite(PROCESS_STATE.UNPACK, null, null, bitState.Value.connectionNumber); if (byteState.Key.Count == 0) return new KeyValuePair(UNPACK_STATUS.ERROR, null); List packet = byteState.Key; //crc test byte[] crc = packet.Skip(len + 1).Take(2).ToArray(); ushort crcShort = (ushort)((crc[0] << 8) | crc[1]); //skip start bytes, crc, and end bytes ushort CalculatedCRC = crc_bytes(packet.Skip(2).Take(len - 1).ToArray()); if (CalculatedCRC != crcShort) { return new KeyValuePair(UNPACK_STATUS.BAD_CRC, packet.ToArray()); } return new KeyValuePair(UNPACK_STATUS.GOOD_MESSAGE, packet.ToArray()); } static public UInt16 crc_bytes(byte[] data) { ushort crc = 0xFFFF; for (int i = 0; i < data.Length; i++) { crc ^= (ushort)(Reflect(data[i], 8) << 8); for (int j = 0; j < 8; j++) { if ((crc & 0x8000) > 0) crc = (ushort)((crc << 1) ^ 0x1021); else crc <<= 1; } } crc = Reflect(crc, 16); crc = (ushort)~crc; return crc; } static public ushort Reflect(ushort data, int size) { ushort output = 0; for (int i = 0; i < size; i++) { int lsb = data & 0x01; output = (ushort)((output << 1) | lsb); data >>= 1; } return output; } static KeyValuePair, StateObject> ReadWrite(PROCESS_STATE ps, Socket handler, IAsyncResult ar, long unpackConnectionNumber) { KeyValuePair, StateObject> byteState = new KeyValuePair, StateObject>(); ; StateObject stateObject = null; int bytesRead = -1; int workingBufferLen = 0; List working_buffer = null; byte[] buffer = null; Object thisLock1 = new Object(); lock (thisLock1) { switch (ps) { case PROCESS_STATE.ACCEPT: acceptDone.WaitOne(); acceptDone.Reset(); stateObject = new StateObject(); stateObject.buffer = new byte[BUFFER_SIZE]; connectionDict.Add(connectionNumber, new KeyValuePair, StateObject>(new List(), stateObject)); stateObject.connectionNumber = connectionNumber++; stateObject.workSocket = handler; byteState = new KeyValuePair, StateObject>(null, stateObject); acceptDone.Set(); break; case PROCESS_STATE.READ: //catch when client disconnects //wait if accept is being called //acceptDone.WaitOne(); try { stateObject = ar.AsyncState as StateObject; // Read data from the client socket. bytesRead = stateObject.workSocket.EndReceive(ar); if (bytesRead > 0) { byteState = connectionDict[stateObject.connectionNumber]; buffer = new byte[bytesRead]; Array.Copy(byteState.Value.buffer, buffer, bytesRead); byteState.Key.AddRange(buffer); } //only put one instance of connection number into fifo if (!fifo.Contains(byteState.Value.connectionNumber)) { fifo.Add(byteState.Value.connectionNumber); } } catch (Exception ex) { //will get here if client disconnects fifo.RemoveAll(x => x == byteState.Value.connectionNumber); connectionDict.Remove(byteState.Value.connectionNumber); byteState = new KeyValuePair, StateObject>(new List(), null); } break; case PROCESS_STATE.PROCESS: if (fifo.Count > 0) { //get message from working buffer //unpack will later delete message //remove connection number from fifo // the list in the key in known as the working buffer byteState = new KeyValuePair, StateObject>(connectionDict[fifo[0]].Key, connectionDict[fifo[0]].Value); fifo.RemoveAt(0); //put a valid value in fifoCount so -1 below can be detected. byteState.Value.fifoCount = fifo.Count; } else { //getting here is normal when there is no more work to be performed //set fifocount to zero so rest of code know fifo was empty so code waits for next receive message byteState = new KeyValuePair, StateObject>(null, new StateObject() { fifoCount = -1 }); } break; case PROCESS_STATE.UNPACK: try { working_buffer = connectionDict[unpackConnectionNumber].Key; workingBufferLen = working_buffer[2]; if ((working_buffer[0] != 0x78) && (working_buffer[1] != 0x78) && (working_buffer[workingBufferLen + 3] != 0x0D) && (working_buffer[workingBufferLen + 4] != 0x0A)) { working_buffer.Clear(); return new KeyValuePair, StateObject>(new List(), null); } List packet = working_buffer.GetRange(0, workingBufferLen + 5); working_buffer.RemoveRange(0, workingBufferLen + 5); byteState = new KeyValuePair, StateObject>(packet, null); } catch (Exception ex) { int testPoint = 0; } break; }// end switch } return byteState; } static void Send(Socket handler, String data) { // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); } static void Send(Socket socket, byte[] data) { // Convert the string data to byte data using ASCII encoding. // byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. socket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), socket); } static void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket handler = ar.AsyncState as Socket; // Complete sending the data to the remote device. int bytesSent = handler.EndSend(ar); // Console.WriteLine("Sent {0} bytes to client.", bytesSent); } catch (Exception e) { // Console.WriteLine(e.ToString()); int myerror = -1; } } public static void AcceptCallback(IAsyncResult ar) { try { // Get the socket that handles the client request. // Retrieve the state object and the handler socket // from the asynchronous state object. Socket listener = (Socket)ar.AsyncState; Socket handler = listener.EndAccept(ar); // Create the state object. StateObject state = ReadWrite(PROCESS_STATE.ACCEPT, handler, ar, -1).Value; handler.BeginReceive(state.buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(ReadCallback), state); } catch (Exception ex) { int myerror = -1; } } public static void ReadCallback(IAsyncResult ar) { try { StateObject state = ar.AsyncState as StateObject; Socket handler = state.workSocket; // Read data from the client socket. KeyValuePair, StateObject> byteState = ReadWrite(PROCESS_STATE.READ, handler, ar, -1); if (byteState.Value != null) { allDone.Set(); handler.BeginReceive(state.buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(ReadCallback), state); } else { int testPoint = 0; } } catch (Exception ex) { int myerror = -1; } // Signal the main thread to continue. allDone.Set(); } } } 

Here is the modified code Section 1 :

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; using System.Data; using System.Data.SqlClient; using System.ComponentModel; using System.Timers; namespace ConcoxServer { public class StateObject { public long connectionNumber = -1; public Socket workSocket { get; set; } public byte[] buffer { get; set; } public int fifoCount { get; set;} public string IMEI { get; set; } } public enum PROTOCOL_NUMBER { LOGIN_MESSAGE = 0x01, LOCATION_DATA = 0x12, STATUS_INFO = 0X13, STRING_INFO = 0X15, ALARM_DATA = 0X16, GPS_QUERY_ADDR_PHONE_NUM = 0X1A, COMMAND_INFO = 0X80, NONE } public enum UNPACK_STATUS { ERROR, NOT_ENOUGH_BYTES, BAD_CRC, GOOD_MESSAGE, DEFAULT } public enum PROCESS_STATE { ACCEPT, READ, PROCESS, UNPACK } public enum ALARM : Byte { NORMAL = 0, SHOCK_ALARM = 1, POWER_CUT_ALARM = 2, LOW_BATTERY = 3, SOS = 4 } class Program { const string IP = "127.0.0.1"; const int PORT = 8841; const Boolean test = true; static void Main(string[] args) { GPS gps = new GPS(IP, PORT, test); Console.WriteLine("Connection Ended"); } } public class GPS { const int BUFFER_SIZE = 1024; const string CONNECT_STRING = @"Data Source=.\SQLEXPRESS;Initial Catalog=GPSTracker;Integrated Security=SSPI;"; const string LOGIN_INSERT_COMMMAND_TEXT = "use GPSTracker INSERT INTO Login (TerminalID,Date) VALUES(@TerminalID,@Date)"; const string LOCATION_INSERT_COMMMAND_TEXT = "INSERT INTO T_Tracking (IMEI,TrackTime, CurrTime, Longitude, Lattitude,speed)" + "VALUES (@IMEI, @TrackTime, @CurrTime, @Longitude, @Lattitude, @speed)"; static SqlConnection conn = null; static SqlCommand cmdLogin = null; static SqlCommand cmdLocation = null; static byte[] loginResponse = { 0x78, 0x78, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A }; static byte[] alarmResponse = { 0x78, 0x78, 0x05, 0x16, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A }; static byte[] alarmDataAddressResponse = { 0x78, 0x78, 0x00, 0x97, 0x7E, 0x00, 0x00, 0x00, 0x01, 0x41, 0x4C, 0x41, 0x52, 0x4D, 0x53, 0x4D, 0x53, //ALARMS 0x26, 0x26, //&& 0x80, 0x00, 0x72, 0x00, 0x79, 0x00, 0x78, 0x00, // PHONE HOME 0x69, 0x00, 0x32, 0x00, 0x72, 0x00, 0x79, 0x00, 0x77, 0x00, 0x69, 0x26, 0x26, //&& 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Phone Numbe 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x23, //## 0x00, 0x00, //serial number 0x00, 0x00, //check bytes 0x0D, 0x0A //stop bytes }; static byte[] heartbeatResponse = { 0x78, 0x78, 0x05, 0x13, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A }; static byte[] connectOilAndEletricity = { 0x78, 0x78, 0x16, 0x80, 0x10, 0x12, 0x34, 0x56, 0x78, 0x48, //server flag bit 0x12345678 0x46, 0x59, 0x44, 0x2C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x23, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A }; static long connectionNumber = 0; //mapping of connection number to StateObject static Dictionary, StateObject>> connectionDict = new Dictionary, StateObject>>(); //fifo contains list of connections number wait with receive data public static List fifo = new List(); public static AutoResetEvent allDone = new AutoResetEvent(false); public static AutoResetEvent acceptDone = new AutoResetEvent(false); public GPS(string IP, int port, Boolean test) { try { conn = new SqlConnection(CONNECT_STRING); conn.Open(); cmdLogin = new SqlCommand(LOGIN_INSERT_COMMMAND_TEXT, conn); cmdLogin.Parameters.Add("@TerminalID", SqlDbType.NVarChar, 8); cmdLogin.Parameters.Add("@Date", SqlDbType.DateTime); cmdLocation = new SqlCommand(LOCATION_INSERT_COMMMAND_TEXT, conn); cmdLocation.Parameters.Add("@IMEI", SqlDbType.NVarChar, 50); cmdLocation.Parameters.Add("@TrackTime", SqlDbType.DateTime); cmdLocation.Parameters.Add("@currTime", SqlDbType.DateTime); cmdLocation.Parameters.Add("@Longitude", SqlDbType.NChar, 50); cmdLocation.Parameters.Add("@Lattitude", SqlDbType.NVarChar, 50); cmdLocation.Parameters.Add("@speed", SqlDbType.Float); } catch (Exception ex) { Console.WriteLine("Error : '{0}'", ex.Message); //Console.ReadLine(); return; } try { //initialize the timer for writing to database. WriteDBAsync.WriteDatabase(); StartListening(IP, port, test); // Open 2nd listener to simulate two devices, Only for testing //StartListening(IP, port + 1, test); ProcessMessages(); } catch (Exception ex) { Console.WriteLine("Error : '{0}'", ex.Message); //Console.ReadLine(); return; } } public enum DATABASE_MESSAGE_TYPE { LOGIN, LOCATION } public class WriteDBMessage { public DATABASE_MESSAGE_TYPE message { get; set; } } public class WriteDBMessageLogin : WriteDBMessage { public DateTime date { get; set; } public string IMEI { get; set; } } public class WriteDBMessageLocation : WriteDBMessage { public string IMEI { get; set; } public DateTime trackTime { get; set; } public DateTime currTime { get; set; } public byte[] longitude { get; set; } public byte[] lattitude { get; set; } public float speed { get; set; } public byte[] courseStatus { get; set; } } public static class WriteDBAsync { public enum Mode { READ, WRITE } public static List fifo = new List(); public static System.Timers.Timer timer = null; public static void WriteDatabase() { timer = new System.Timers.Timer(1000); timer.Elapsed += Timer_Elapsed; timer.Start(); } public static WriteDBMessage ReadWriteFifo(Mode mode, WriteDBMessage message) { Object thisLock2 = new Object(); lock (thisLock2) { switch (mode) { case Mode.READ: if(fifo.Count > 0) { message = fifo[0]; fifo.RemoveAt(0); } break; case Mode.WRITE: fifo.Add(message); break; } } return message; } static void Timer_Elapsed(object sender, ElapsedEventArgs e) { timer.Enabled = false; WriteDBMessage row = null; int rowsAdded = 0; uint number = 0; double lat = 0; string latStr = ""; double lon = 0; string longStr = ""; int degrees = 0; double minutes = 0; try { while((row = ReadWriteFifo(Mode.READ, null)) != null) { switch(row.message) { case DATABASE_MESSAGE_TYPE.LOGIN: cmdLogin.Parameters["@TerminalID"].Value = ((WriteDBMessageLogin)row).IMEI; cmdLogin.Parameters["@Date"].Value = ((WriteDBMessageLogin)row).date; rowsAdded = cmdLogin.ExecuteNonQuery(); break; case DATABASE_MESSAGE_TYPE.LOCATION: cmdLocation.Parameters["@IMEI"].Value = ((WriteDBMessageLocation)row).IMEI; cmdLocation.Parameters["@TrackTime"].Value = ((WriteDBMessageLocation)row).trackTime; cmdLocation.Parameters["@currTime"].Value = ((WriteDBMessageLocation)row).currTime; number = BitConverter.ToUInt32(((WriteDBMessageLocation)row).longitude.Reverse().ToArray(), 0); lon = (180 * number) / 324000000.0; degrees = (int)lon; minutes = 60 * (lon - degrees); longStr = string.Format("{0}º{1}{2}", degrees, minutes, (((WriteDBMessageLocation)row).courseStatus[0] & 0x08) == 0 ? "E" : "W"); cmdLocation.Parameters["@Longitude"].Value = longStr; number = BitConverter.ToUInt32(((WriteDBMessageLocation)row).lattitude.Reverse().ToArray(), 0); lat = (90 * number) / 162000000.0; degrees = (int)lat; minutes = 60 * (lat - degrees); latStr = string.Format("{0}º{1}{2}", degrees, minutes, (((WriteDBMessageLocation)row).courseStatus[0] & 0x04) == 0 ? "S" : "N"); cmdLocation.Parameters["@Lattitude"].Value = latStr; cmdLocation.Parameters["@speed"].Value = ((WriteDBMessageLocation)row).speed; rowsAdded = cmdLocation.ExecuteNonQuery(); break; } } } catch (Exception ex) { //Console.WriteLine("Error : '{0}'", ex.Message); } timer.Enabled = true; } } public void StartListening(string IP, int port, Boolean test) { try { // Establish the local endpoint for the socket. // The DNS name of the computer // running the listener is "host.contoso.com". IPHostEntry ipHostInfo = Dns.GetHostEntry(IP); //Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress = ipHostInfo.AddressList[0]; //IPAddress local = IPAddress.Parse(IP); IPEndPoint localEndPoint = null; if (test) { localEndPoint = new IPEndPoint(IPAddress.Any, port); } else { localEndPoint = new IPEndPoint(ipAddress, port); } // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Bind the socket to the local endpoint and listen for incoming connections. allDone.Reset(); acceptDone.Reset(); listener.Bind(localEndPoint); listener.Listen(100); //login code, wait for 1st message Console.WriteLine("Wait 5 seconds for login message"); listener.BeginAccept(new AsyncCallback(AcceptCallback), listener); } catch (Exception e) { Console.WriteLine(e.Message); } } 

Here is my test client with 5 messages

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Globalization; using System.Threading; namespace ConcoxClient { class Program { const int PORT = 8841; static void Main(string[] args) { string IP = "xxxx"; string loginMessage1 = "7878110103587390503134452020000100196A930D0A"; string locationDataMessage1 = "78781F120B081D112E10CF027AC7EB0C46584900148F01CC00287D001FB8000380810D0A"; string alarmmMessage1 = "787825160B0B0F0E241DCF027AC8870C4657E60014020901CC00287D001F726506040101003656A40D0A"; string heartMessage1 = "78780A134401040001000508450D0A"; string heartPowerCutAlarmMessage1 = "78780A131001040001000515FC0D0A"; string connectOilMessage1 = "78781915110001A963484659443D53756363657373210002001EF8930D0A"; string[] messages1 = { loginMessage1, locationDataMessage1, alarmmMessage1, heartMessage1, heartPowerCutAlarmMessage1, connectOilMessage1 }; string loginMessage2 = "787811010358739050313446202000010091CABD0D0A"; string locationDataMessage2 = "78781F12110612112E10CF027AC7EB0C46584900148F01CC00287D001FB800039AA10D0A"; string alarmmMessage2 = "787825161106180E241DCF027AC8870C4657E60014020901CC00287D001F726506040101003606FD0D0A"; string[] messages2 = { loginMessage2, locationDataMessage2, alarmmMessage2 }; IPHostEntry ipHostInfo = Dns.GetHostEntry(IP); //Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress = ipHostInfo.AddressList[0]; IPAddress local = IPAddress.Parse(IP); TcpClient client1 = new TcpClient(); client1.Connect(IP, PORT); //TcpClient client2 = new TcpClient(); //client2.Connect(IP, PORT + 1); while (true) { foreach (string message in messages1) { byte[] messageBytes = new byte[message.Length / 2]; for (int i = 0; i < message.Length; i += 2) { messageBytes[i / 2] = byte.Parse(message.Substring(i, 2), NumberStyles.HexNumber); } client1.Client.Send(messageBytes); //System.Threading.Thread.Sleep(1000); } foreach (string message in messages2) { byte[] messageBytes = new byte[message.Length / 2]; for (int i = 0; i < message.Length; i += 2) { messageBytes[i / 2] = byte.Parse(message.Substring(i, 2), NumberStyles.HexNumber); } //client2.Client.Send(messageBytes); //System.Threading.Thread.Sleep(1000); } Console.WriteLine("Hit return to send another message"); Console.ReadLine(); } } } }