Beispiel #1
0
        /// <summary>
        /// 解析8字节命令部分
        /// </summary>
        /// <param name="e"></param>
        private void ProcessReceivePackagePrefix(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            LogHelper.Log.InfoFormat("客户端{0}:In ProcessReceivePackagePrefix", token.Socket.RemoteEndPoint.ToString());
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                for (int i = e.Offset; i < e.BytesTransferred; i++)
                {
                    token.resultBytes.Add(e.Buffer[i]);
                }

                if (token.resultBytes.Count < token.Length)
                {
                    e.SetBuffer(e.Offset, token.Length - token.resultBytes.Count);
                    token.CommandType = CommandType.PackagePrefix;
                    bool willRaiseEvent = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }
                }
                else
                {
                    BasicPackage package = SocketHelper.BytesToStruct <BasicPackage>(token.resultBytes.ToArray());
                    package.PID = SocketHelper.NetworkToHost(package.PID);
                    package.CID = SocketHelper.NetworkToHost(package.CID);
                    package.VER = SocketHelper.NetworkToHost(package.VER);
                    token.resultBytes.Clear();
                    if (package.VER == FuncCode.ALPVERSION)
                    {
                        token.BasicPackage = package;
                        this.ParseCommand(e);
                    }
                    else
                    {
                        this.CloseClientSocket(e);
                        LogHelper.Log.InfoFormat("协议版本错误,当前版为:{0},需求版本为:{1}", package.VER, FuncCode.ALPVERSION);
                    }
                }
            }
            else
            {
                this.CloseClientSocket(e);
            }
        }
Beispiel #2
0
        /// <summary>
        /// 关闭连接,释放资源
        /// </summary>
        /// <param name="e"></param>
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = e.UserToken as AsyncUserToken;

            LogHelper.Log.InfoFormat("客户端{0}:In CloseClientSocket", token.Socket.RemoteEndPoint.ToString());
            try
            {
                token.Socket.Shutdown(SocketShutdown.Send);
            }
            catch (Exception)
            {
            }

            token.Socket.Close();
            token       = null;
            e.UserToken = null;
            e.UserToken = new AsyncUserToken();
            Interlocked.Decrement(ref this.m_numConnectedSockets);
            this.m_maxNumberAcceptedClients.Release();
            this.m_readWritePool.Push(e);
            this.m_UsedObjects.Remove(e);
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="e"></param>
        private void ProcessSend(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            LogHelper.Log.InfoFormat("客户端{0}:In ProcessSend", token.Socket.RemoteEndPoint.ToString());
            if (e.SocketError == SocketError.Success)
            {
                bool willRaiseEvent = false;
                switch (token.CommandType)
                {
                case CommandType.Ensure:
                case CommandType.Login:
                case CommandType.EnumData:
                case CommandType.PushDataRequest:
                case CommandType.NullCommand:
                case CommandType.PushDataReply:
                    token.CommandType = CommandType.PackagePrefix;
                    e.SetBuffer(e.Offset, PackgeSize.BasicPackageSize);
                    willRaiseEvent = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }

                    break;

                case CommandType.Close:
                    this.CloseClientSocket(e);
                    break;

                default: break;
                }
            }
            else
            {
                this.CloseClientSocket(e);
            }
        }
Beispiel #4
0
        /// <summary>
        /// 获取数据项的值部分
        /// </summary>
        /// <param name="e"></param>
        private void ProcessReceivePushDataRecordBody(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            LogHelper.Log.InfoFormat(
                "客户端{0}:In ProcessReceivePushDataRecordBody",
                token.Socket.RemoteEndPoint.ToString());
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                for (int i = e.Offset; i < e.BytesTransferred; i++)
                {
                    token.resultBytes.Add(e.Buffer[i]);
                }

                if (token.resultBytes.Count < token.Length)
                {
                    e.SetBuffer(e.Offset, token.Length - token.resultBytes.Count);
                    token.CommandType = CommandType.PushDataRecordBody;
                    bool willRaiseEvent = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }
                }
                else
                {
                    token.Value = token.resultBytes.ToArray();
                    var item = new DataItem()
                    {
                        Id = token.DID, Type = token.DT, Value = token.Value
                    };
                    LogHelper.Log.InfoFormat(
                        "客户端{0}:接收到数据项编号 - {1},类型 - {2},值 - {3}",
                        token.Socket.RemoteEndPoint.ToString(),
                        token.DID,
                        token.DT,
                        SocketHelper.GetValueByType(item));
                    token.DataItems.Add(item);
                    token.InsertedCount++;
                    token.resultBytes.Clear();
                    if (token.InsertedCount < token.CollectDataCount)
                    {
                        token.CommandType = CommandType.PushDataRecordHead;
                        e.SetBuffer(e.Offset, PackgeSize.BasicPackageSize);
                        bool willRaiseEvent = token.Socket.ReceiveAsync(e);
                        if (!willRaiseEvent)
                        {
                            this.ProcessReceive(e);
                        }
                    }
                    else
                    {
                        if (token.MongoHelper.InsertValueToMongo(token.Machine, token.DataItems) == 1)
                        {
                            LogHelper.Log.InfoFormat(
                                "客户端{0}:所有推送数据已接收,等待下一次推送",
                                token.Socket.RemoteEndPoint.ToString());
                            token.DataItems.Clear();
                            token.InsertedCount = 0;
                            LogHelper.Log.InfoFormat("客户端{0}:发送推送数据回复", token.Socket.RemoteEndPoint.ToString());
                            token.CommandType = CommandType.PushDataReply;
                            BasicPackage package8 = new BasicPackage();
                            package8.PID = SocketHelper.HostToNetwork((ushort)0x0000);
                            package8.CID = SocketHelper.HostToNetwork(FuncCode.PushDataReply);
                            package8.ST  = 0;
                            package8.UID = Convert.ToByte(token.UserName);
                            package8.VER = SocketHelper.HostToNetwork((ushort)0x1000);
                            var result = SocketHelper.StructToBytes(package8);
                            e.SetBuffer(e.Offset, 8);
                            Buffer.BlockCopy(result, e.Offset, e.Buffer, 0, 8);
                            LogHelper.Log.InfoFormat(
                                "向客户端{0}:发送登录请求报文,长度为{1}",
                                token.Socket.RemoteEndPoint.ToString(),
                                result.Length);
                            bool willRaiseEvent = token.Socket.SendAsync(e);
                            if (!willRaiseEvent)
                            {
                                this.ProcessSend(e);
                            }
                        }
                        else
                        {
                            this.CloseClientSocket(e);
                        }
                    }
                }
            }
            else
            {
                this.CloseClientSocket(e);
            }
        }
Beispiel #5
0
        /// <summary>
        /// 解析具体枚举数据项
        /// </summary>
        /// <param name="e"></param>
        private void ProcessReceiveEnumDataRecord(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            LogHelper.Log.InfoFormat("客户端{0}:In ProcessReceiveEnumDataRecord", token.Socket.RemoteEndPoint.ToString());
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                for (int i = e.Offset; i < e.BytesTransferred; i++)
                {
                    token.resultBytes.Add(e.Buffer[i]);
                }

                if (token.resultBytes.Count < token.Length)
                {
                    e.SetBuffer(e.Offset, token.Length - token.resultBytes.Count);
                    token.CommandType = CommandType.EnumDataRecord;
                    bool willRaiseEvent = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }
                }
                else
                {
                    EnumDataRecordPackage package =
                        SocketHelper.BytesToStruct <EnumDataRecordPackage>(token.resultBytes.ToArray());
                    package.DID = SocketHelper.NetworkToHost(package.DID);
                    token.Machine.Map.MapArray.Add(
                        new MapArray()
                    {
                        Id = package.DID.ToString(), Value = package.NAME
                    });
                    LogHelper.Log.InfoFormat(
                        "客户端{0}:接收枚举数据项编号{1},名称{2}",
                        token.Socket.RemoteEndPoint.ToString(),
                        package.DID.ToString(),
                        package.NAME);
                    token.InsertedCount++;
                    token.resultBytes.Clear();
                    if (token.InsertedCount < token.MappedFieldCount)
                    {
                        e.SetBuffer(e.Offset, PackgeSize.EnumDataPackageSize);
                        token.CommandType = CommandType.EnumDataRecord;
                        bool willRaiseEvent = token.Socket.ReceiveAsync(e);
                        if (!willRaiseEvent)
                        {
                            this.ProcessReceive(e);
                        }
                    }
                    else
                    {
                        token.InsertedCount = 0;
                        if (token.MongoHelper.InsertMappedFiled(token.Machine) == 1)
                        {
                            RequestPushPackage package6 = new RequestPushPackage();
                            package6.PID = SocketHelper.HostToNetwork((ushort)0x0000);
                            package6.CID = SocketHelper.HostToNetwork(FuncCode.PushDataRequest);
                            package6.UID = (byte)token.UserName;
                            package6.ST  = 0;
                            package6.VER = SocketHelper.HostToNetwork((ushort)0x1000);
                            package6.RV  = new byte[8] {
                                0, 0, 0, 0, 0, 0, 0, 0
                            };
                            token.CommandType = CommandType.PushDataRequest;
                            var result = SocketHelper.StructToBytes(package6);
                            e.SetBuffer(e.Offset, PackgeSize.RequestPushPackageSize);
                            Buffer.BlockCopy(result, e.Offset, e.Buffer, 0, PackgeSize.RequestPushPackageSize);
                            LogHelper.Log.InfoFormat(
                                "向客户端{0}:发送推送数据请求报文,长度为{1}",
                                token.Socket.RemoteEndPoint.ToString(),
                                result.Length);
                            bool willRaiseEvent = token.Socket.SendAsync(e);
                            if (!willRaiseEvent)
                            {
                                this.ProcessSend(e);
                            }
                        }
                        else
                        {
                            this.CloseClientSocket(e);
                        }
                    }
                }
            }
            else
            {
                this.CloseClientSocket(e);
            }
        }
Beispiel #6
0
        /// <summary>
        /// 设备自举
        /// </summary>
        /// <param name="e"></param>
        private void ProcessReceiveBootstrap(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            LogHelper.Log.InfoFormat("客户端{0}:In ProcessReceivePackagePrefix", token.Socket.RemoteEndPoint.ToString());
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                for (int i = e.Offset; i < e.BytesTransferred; i++)
                {
                    token.resultBytes.Add(e.Buffer[i]);
                }

                if (token.resultBytes.Count < token.Length)
                {
                    e.SetBuffer(e.Offset, token.Length - token.resultBytes.Count);
                    token.CommandType = CommandType.Bootstrap;
                    bool willRaiseEvent = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }
                }
                else
                {
                    MacBootstrapPackage package =
                        SocketHelper.BytesToStruct <MacBootstrapPackage>(token.resultBytes.ToArray());
                    token.Machine.MachineCode = SocketHelper.BinToHexString(package.DID).TrimEnd().ToUpper();
                    LogHelper.Log.InfoFormat(
                        "客户端{0}:接收到自举设备编号{1}",
                        token.Socket.RemoteEndPoint.ToString(),
                        token.Machine.MachineCode);
                    token.resultBytes.Clear();
                    if (token.MongoHelper.GetMacLoginInfo(token) == 1)
                    {
                        LoginPackage package4 = new LoginPackage();
                        package4.PID      = SocketHelper.HostToNetwork((ushort)0x0000);
                        package4.CID      = SocketHelper.HostToNetwork(FuncCode.Login);
                        package4.ST       = 0;
                        package4.UID      = Convert.ToByte(token.UserName);
                        package4.VER      = SocketHelper.HostToNetwork((ushort)0x1000);
                        package4.Password = token.Password.PadRight(8, '\0');
                        token.CommandType = CommandType.Login;
                        var result = SocketHelper.StructToBytes(package4);
                        e.SetBuffer(e.Offset, 16);
                        Buffer.BlockCopy(result, e.Offset, e.Buffer, 0, 16);
                        LogHelper.Log.InfoFormat(
                            "向客户端{0}:发送登录请求报文,长度为{1}",
                            token.Socket.RemoteEndPoint.ToString(),
                            result.Length);
                        bool willRaiseEvent = token.Socket.SendAsync(e);
                        if (!willRaiseEvent)
                        {
                            this.ProcessSend(e);
                        }
                    }
                    else
                    {
                        this.CloseClientSocket(e);
                        LogHelper.Log.InfoFormat("没有该设备的登录信息或设备已停用");
                    }
                }
            }
            else
            {
                this.CloseClientSocket(e);
            }
        }
Beispiel #7
0
        /// <summary>
        /// ProcessReceive
        /// </summary>
        /// <param name="e"></param>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            LogHelper.Log.InfoFormat("客户端{0}:In ProcessReceive", token.Socket.RemoteEndPoint.ToString());
            if (e.SocketError == SocketError.Success)
            {
                switch (token.CommandType)
                {
                case CommandType.PackagePrefix:
                    token.Length = 8;
                    this.ProcessReceivePackagePrefix(e);
                    break;

                case CommandType.Bootstrap:
                    token.Length = 32;
                    this.ProcessReceiveBootstrap(e);
                    break;

                case CommandType.Login:
                    token.Length = 8;
                    this.ProcessReceiveLogin(e);
                    break;

                case CommandType.EnumDataCount:
                    token.Length = 8;
                    this.ProcessReceiveEnumDataCount(e);
                    break;

                case CommandType.EnumDataRecord:
                    token.Length = 104;
                    this.ProcessReceiveEnumDataRecord(e);
                    break;

                case CommandType.PushDataRequest:
                    token.Length = 8;
                    this.ProcessReceivePushDataRequest(e);
                    break;

                case CommandType.PushDataCount:
                    token.Length = 8;
                    this.ProcessReceivePushDataCount(e);
                    break;

                case CommandType.PushDataRecordHead:
                    token.Length = 8;
                    this.ProcessReceivePushDataRecordHead(e);
                    break;

                case CommandType.PushDataRecordBody:
                    this.ProcessReceivePushDataRecordBody(e);
                    break;

                case CommandType.Close:
                    this.CloseClientSocket(e);
                    break;

                case CommandType.NullCommand:
                    token.CommandType = CommandType.NullCommandReply;
                    this.ProcessSend(e);
                    break;

                default: break;
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// 解析命令
        /// </summary>
        /// <param name="token"></param>
        private void ParseCommand(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            LogHelper.Log.InfoFormat("客户端{0}:In ParseCommand", token.Socket.RemoteEndPoint.ToString());
            if (e.SocketError == SocketError.Success)
            {
                bool willRaiseEvent = false;
                switch (token.BasicPackage.CID)
                {
                case FuncCode.Bootstrap:
                    e.SetBuffer(e.Offset, PackgeSize.MacBootstrapPackageSize);
                    token.CommandType = CommandType.Bootstrap;
                    willRaiseEvent    = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }

                    break;

                case FuncCode.Login:
                    e.SetBuffer(e.Offset, PackgeSize.LoginPackageSize - PackgeSize.BasicPackageSize);
                    token.CommandType = CommandType.Login;
                    willRaiseEvent    = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }

                    break;

                case FuncCode.EnumData:
                    e.SetBuffer(e.Offset, PackgeSize.LoginPackageSize - PackgeSize.BasicPackageSize);
                    token.CommandType = CommandType.EnumDataCount;
                    willRaiseEvent    = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }

                    break;

                case FuncCode.PushDataRequest:
                    e.SetBuffer(e.Offset, PackgeSize.LoginPackageSize - PackgeSize.BasicPackageSize);
                    token.CommandType = CommandType.PushDataRequest;
                    willRaiseEvent    = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }

                    break;

                case FuncCode.PushData:
                    e.SetBuffer(e.Offset, PackgeSize.LoginPackageSize - PackgeSize.BasicPackageSize);
                    token.CommandType = CommandType.PushDataCount;
                    willRaiseEvent    = token.Socket.ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }

                    break;

                case FuncCode.NullCommand:
                    BasicPackage package7 = new BasicPackage();
                    package7.PID = SocketHelper.HostToNetwork((ushort)0x0000);
                    package7.CID = SocketHelper.HostToNetwork(FuncCode.NullCommandReply);
                    package7.ST  = 0;
                    package7.UID = Convert.ToByte(token.UserName);
                    package7.VER = SocketHelper.HostToNetwork((ushort)0x1000);
                    var result = SocketHelper.StructToBytes(package7);
                    token.CommandType = CommandType.NullCommand;
                    e.SetBuffer(e.Offset, 8);
                    Buffer.BlockCopy(result, e.Offset, e.Buffer, 0, 8);
                    LogHelper.Log.InfoFormat(
                        "向客户端{0}发送心跳包回复报文,长度为{1}",
                        token.Socket.RemoteEndPoint.ToString(),
                        result.Length);
                    willRaiseEvent = token.Socket.SendAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessSend(e);
                    }

                    break;

                case FuncCode.Close:
                    this.CloseClientSocket(e);
                    break;

                default: break;
                }
            }
            else
            {
                this.CloseClientSocket(e);
            }
        }
Beispiel #9
0
        /// <summary>
        /// 守护线程检测会话超时
        /// </summary>
        private void DaemonThreadStart()
        {
            while (this.m_thread.IsAlive)
            {
                LogHelper.Log.InfoFormat("当前连接数量{0}", this.m_UsedObjects.Count);
                for (int i = 0; i < this.m_UsedObjects.Count; i++)
                {
                    if (!this.m_thread.IsAlive)
                    {
                        break;
                    }

                    try
                    {
                        lock (this.m_UsedObjects[i].UserToken)
                        {
                            AsyncUserToken token = this.m_UsedObjects[i].UserToken as AsyncUserToken;
                            if (token != null)
                            {
                                var currentDateTime = DateTime.Now;
                                if ((currentDateTime - token.ActiveDateTime).TotalSeconds
                                    > SocketTimeOutMS)
                                {
                                    // 超时Socket断开
                                    LogHelper.Log.InfoFormat(
                                        "连接超时,当前连接设备为{0},当前时间为{1},最后通讯时间为{2}",
                                        token.TenantId,
                                        currentDateTime,
                                        token.ActiveDateTime);
                                    if (token.IsLogined)
                                    {
                                        // 设置此时设备是离线状态
                                        StateArray item =
                                            new StateArray()
                                        {
                                            Code         = "4",
                                            CreationTime = DateTime.Now.ToString("yyyyMMddHHmmss")
                                        };
                                        token.MongoHelper.InsertStateData(
                                            token.Machine.TenantId,
                                            token.Machine.MachineCode,
                                            item);

                                        // 结束报警时间
                                        AlarmArray item2 =
                                            new AlarmArray()
                                        {
                                            Code         = "0",
                                            CreationTime = DateTime.Now.ToString("yyyyMMddHHmmss")
                                        };
                                        token.MongoHelper.InsertAlarmData(
                                            token.Machine.TenantId,
                                            token.Machine.MachineCode,
                                            item2);
                                    }

                                    this.CloseClientSocket(this.m_UsedObjects[i]);
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        CGLogger.Error(e.Message.ToString());
                    }
                }

                for (int i = 0; i < 60; i++)
                {
                    // 每分钟检测一次
                    if (!this.m_thread.IsAlive)
                    {
                        break;
                    }
                    Thread.Sleep(1000);
                }
            }
        }