c# - GPS 套接字通信 (CONCOX)

标签 c# sockets

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

enter image description here

我可以收到登录信息 787811010XXX739050313XXX20200001000E0EAD0D0A

     IMEI Sart With XXX

数据包与示例图像不同

我有两个问题 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<byte> bytes = new List<byte>();

    // 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 < 8; j++)
        {
            if ((crc & 0x8000) > 0)
                crc = (ushort)((crc << 1) ^ 0x1021);
            else
                crc <<= 1;
        }
    }

    return crc;
}
public static void ReadCallback(IAsyncResult ar)
{
    String content = String.Empty;

    // Retrieve the state object and the handler socket
    // from the asynchronous state object.
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    // Read data from the client socket. 
    int bytesRead = handler.EndReceive(ar);

    if (bytesRead > 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. Error Check A check code may be used by the terminal or the server to distinguish whether the received information is error or not. To prevent errors occur during data transmission, error check is added to against data misoperation, so as to increase the security and efficiency of the system. The check code is generated by the CRC-ITU checking method. The check codes of data in the structure of the protocol, from the Packet Length to the Information Serial Number (including “Packet Length” and “Information Serial Number”) , are values of CRC-ITU. CRC error occur when the received information is calculated, the receiver will ignore and discard the data packet. 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;

enter image description here

状态信息 enter image description here

最佳答案

这是第 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<List<byte>, StateObject> byteState;
            KeyValuePair<UNPACK_STATUS, byte[]> 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_STATUS, byte[]> Unpack(KeyValuePair<List<byte>, StateObject> bitState)
        {
            List<byte> working_buffer = bitState.Key;
            //return null indicates an error
            if (working_buffer.Count() < 3) return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.NOT_ENOUGH_BYTES, null);

            int len = working_buffer[2];

            if (working_buffer.Count < len + 5) return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.NOT_ENOUGH_BYTES, null);
            // check start and end bytes
            // remove message fro workig buffer and dictionary 
            KeyValuePair<List<byte>, StateObject> byteState = ReadWrite(PROCESS_STATE.UNPACK, null, null, bitState.Value.connectionNumber);
            if (byteState.Key.Count == 0) return new KeyValuePair<UNPACK_STATUS, byte[]>(UNPACK_STATUS.ERROR, null);

            List<byte> 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, byte[]>(UNPACK_STATUS.BAD_CRC, packet.ToArray());
            }

            return new KeyValuePair<UNPACK_STATUS, byte[]>(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<List<byte>, StateObject> ReadWrite(PROCESS_STATE ps, Socket handler, IAsyncResult ar, long unpackConnectionNumber)
        {
            KeyValuePair<List<byte>, StateObject> byteState = new KeyValuePair<List<byte>, StateObject>(); ;
            StateObject stateObject = null;
            int bytesRead = -1;
            int workingBufferLen = 0;
            List<byte> 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<List<byte>, StateObject>(new List<byte>(), stateObject));
                        stateObject.connectionNumber = connectionNumber++;

                        stateObject.workSocket = handler;

                        byteState = new KeyValuePair<List<byte>, 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<List<byte>, StateObject>(new List<byte>(), 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<List<byte>, 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<List<byte>, 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<List<byte>, StateObject>(new List<byte>(), null);
                            }
                            List<byte> packet = working_buffer.GetRange(0, workingBufferLen + 5);
                            working_buffer.RemoveRange(0, workingBufferLen + 5);
                            byteState = new KeyValuePair<List<byte>, 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<List<byte>, 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();
        }
    }
}

关于c# - GPS 套接字通信 (CONCOX),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44471975/

相关文章:

c# - 生成带步长值的序列

c# - ASP.NET MVC 4 Controller 失败找不到与名为 'account' 的 Controller 匹配的类型

c# - 是否可以从 IronPython 调用重载的 C# 构造函数?

python - 附加到子 Python 子进程的套接字未正确释放

sockets - SOCKS和socket有什么关系?

java - SSL套接字帮助-javax.net.ssl.SSLHandshakeException : Received fatal alert: certificate_unknown

c# - 包含List <Object>作为项目源的DisplayMember组合框

c# - 服务器上存在文件,但列表目录命令未返回

java - Safari 5/iOS,WebSocket 握手有时有效

sockets - golang 套接字在 Write() 方法返回之前不发送所有字节