Пример #1
0
        public void StartListening(string IP, int port, Boolean test)
        {
            // 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);
            UInt16     sendCRC = 0;
            DateTime   date;
            int        year          = 0;
            int        month         = 0;
            int        day           = 0;
            int        hour          = 0;
            int        minute        = 0;
            int        second        = 0;
            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.
            try
            {
                allDone.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);
                Boolean firstMessage = true;
                //loop forever
                while (true)
                {
                    allDone.WaitOne();
                    //read fifo until empty
                    while (fifo.Count > 0)
                    {
                        //read one connection until buffer doesn't contain any more packets
                        KeyValuePair <List <byte>, StateObject> byteState = ReadWrite(-1, PROCESS_STATE.PROCESS, null, null, null);
                        StateObject state = byteState.Value;
                        while (true)
                        {
                            KeyValuePair <UNPACK_STATUS, byte[]> status = Unpack(byteState.Key);
                            if (status.Key == UNPACK_STATUS.NOT_ENOUGH_BYTES)
                            {
                                break;
                            }
                            //message is 2 start bytes + 1 byte (message length) + 1 byte message length + 2 end bytes
                            byte[] receiveMessage = status.Value;

                            if (status.Key != UNPACK_STATUS.GOOD_MESSAGE)
                            {
                                int zzz = -1;
                            }
                            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)
                            {
                                Console.WriteLine("Error : Bad Login Message, Data : '{0}'", BytesToString(receiveMessage));
                                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)
                                byte[]          serialNumber   = receiveMessage.Skip(2 + 1 + messageLength - 4).Take(2).ToArray();
                                PROTOCOL_NUMBER protocolNumber = (PROTOCOL_NUMBER)receiveMessage[3];
                                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());
                                    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);
            }
        }
Пример #2
0
        static KeyValuePair <List <byte>, StateObject> ReadWrite(long connectionNumber, PROCESS_STATE ps, Socket handler, IAsyncResult ar, List <byte> working_buffer)
        {
            KeyValuePair <List <byte>, StateObject> byteState = new KeyValuePair <List <byte>, StateObject>();;
            StateObject state    = null;
            Object      thisLock = new Object();

            lock (thisLock)
            {
                switch (ps)
                {
                case PROCESS_STATE.ACCEPT:
                    state                  = new StateObject();
                    state.buffer           = new byte[BUFFER_SIZE];
                    state.connectionNumber = connectionNumber;
                    connectionDict.Add(connectionNumber++, new KeyValuePair <List <byte>, StateObject>(new List <byte>(), state));
                    // Create the state object.
                    state.workSocket = handler;
                    byteState        = new KeyValuePair <List <byte>, StateObject>(null, state);
                    break;

                case PROCESS_STATE.READ:
                    //catch when client disconnects
                    try
                    {
                        // Read data from the client socket.
                        int bytesReads = handler.EndReceive(ar);
                        if (bytesReads > 0)
                        {
                            byteState = connectionDict[connectionNumber];
                            byteState.Key.AddRange(byteState.Value.buffer.Take(bytesReads).ToArray());
                        }
                        //only put one instance of connection number into fifo
                        if (!fifo.Contains(connectionNumber))
                        {
                            fifo.Add(connectionNumber);
                        }
                    }
                    catch (Exception ex)
                    {
                        fifo.RemoveAll(x => x == connectionNumber);
                        connectionDict.Remove(connectionNumber);
                        byteState = new KeyValuePair <List <byte>, StateObject>();
                    }
                    break;

                case PROCESS_STATE.PROCESS:
                    if (fifo.Count > 0)
                    {
                        byteState = connectionDict[fifo.First()];
                        fifo.RemoveAt(0);
                        byteState.Key.AddRange(byteState.Key);
                    }
                    break;

                case PROCESS_STATE.UNPACK:
                    int len = working_buffer[2];
                    if ((working_buffer[0] != 0x78) && (working_buffer[1] != 0x78) && (working_buffer[len + 3] != 0x0D) && (working_buffer[len + 4] != 0x0A))
                    {
                        working_buffer.Clear();
                        return(new KeyValuePair <List <byte>, StateObject>(null, null));
                    }
                    List <byte> packet = working_buffer.Take(len + 5).ToList();
                    working_buffer.RemoveRange(0, len + 5);
                    byteState = new KeyValuePair <List <byte>, StateObject>(packet, null);
                    break;
                }    // end switch
            }
            return(byteState);
        }