Exemple #1
0
        private async Task AddLog(TcpAcceptContext token)
        {
            TcpListenerLog log = new TcpListenerLog()
            {
                IsError         = !token.ExecuteSuccess,
                ErrorMessage    = token.ExecuteError ?? string.Empty,
                ExecuteDuration = (int)token.Watch.ElapsedMilliseconds,
                ListenerName    = _listener.Name,
                RequestContent  = UTF8Encoding.UTF8.GetString(token.RetrieveBytes.ToArray()),
                RequestTime     = token.RequestDateTime,
                ResponseContent = token.ResponseBytes == null ? string.Empty : UTF8Encoding.UTF8.GetString(token.ResponseBytes.ToArray()),
                ResponseTime    = DateTime.UtcNow
            };
            var t = Task.Run(async() =>
            {
                try
                {
                    await log.Add();
                }
                catch (Exception ex)
                {
                    LoggerHelper.LogError(LogCategoryName, $"TcpListener {_listener.Name}, AddLog Error,message:{ex.Message},stack:{ex.StackTrace}");
                }
            });

            await Task.FromResult(0);
        }
Exemple #2
0
        //数据发送处理
        private async Task ProcessSend(SocketAsyncEventArgs e)
        {
            TcpAcceptContext token = (TcpAcceptContext)e.UserToken;

            if (e.SocketError == SocketError.Success)
            {
                if (!_listener.KeepAlive)
                {
                    lock (token.LockObj)
                    {
                        token.Status = -1;
                    }
                }
                else
                {
                    token.LatestRunning = DateTime.UtcNow;
                    lock (token.LockObj)
                    {
                        token.Status = 1;
                    }
                }
            }
            else
            {
                lock (token.LockObj)
                {
                    token.Status = -1;
                }
            }
            token.ReleaseReceiveSemaphore();


            await Task.FromResult(0);
        }
Exemple #3
0
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            TcpAcceptContext token = (TcpAcceptContext)e.UserToken;

            lock (token)
            {
                Socket currentSocket = e.AcceptSocket;

                try
                {
                    if (currentSocket != null)
                    {
                        currentSocket.Close();
                    }
                }
                catch
                {
                }

                //重新设置连接上下文
                token.SocketAsyncEventArgs = null;
                token.Status = 0;
                token.ReleaseReceiveSemaphore();
                _tcpAcceptContextPool.Return(token);
            }
        }
Exemple #4
0
        private async Task <InnerDoProcessReceiveResult> InnerDoProcessReceive(SocketAsyncEventArgs e, bool useSocket = false, byte[] buffer = null)
        {
            InnerDoProcessReceiveResult result = new InnerDoProcessReceiveResult();

            TcpAcceptContext token = (TcpAcceptContext)e.UserToken;

            if (!useSocket)
            {
                //将数据加入到接收上下文中
                token.RetrieveBytes.AddRange(e.Buffer.Take(e.BytesTransferred));
            }
            else
            {
                var bufferLength = e.AcceptSocket.Receive(buffer);

                token.RetrieveBytes.AddRange(buffer.Take(bufferLength));
            }


            //如果有尚未接收完成的数据,继续接收


            if (e.AcceptSocket.Available > 0)
            {
                if (buffer == null)
                {
                    buffer = new byte[e.Buffer.Length];
                }

                result.Complete = false;
                result.Buffer   = buffer;
                return(await Task.FromResult(result));
            }
            else
            {
                result.Complete = true;
                result.Buffer   = buffer;
                return(await Task.FromResult(result));
            }
        }
Exemple #5
0
        private async Task DoProcessReceive(SocketAsyncEventArgs e, bool useSocket = false, byte[] buffer = null)
        {
            TcpAcceptContext token = (TcpAcceptContext)e.UserToken;
            var innerResult        = await InnerDoProcessReceive(e, useSocket, buffer);

            while (!innerResult.Complete)
            {
                innerResult = await InnerDoProcessReceive(e, true, innerResult.Buffer);
            }

            bool willRaiseEvent;
            //处理接收到的数据
            var strData = UTF8Encoding.UTF8.GetString(token.RetrieveBytes.ToArray());


            //创建接收处理上下文

            //检查是否是心跳包
            //心跳包的格式固定为字符串“HeartBeat”
            if (strData.ToLower() == _listener.HeartBeatSendData.ToLower())
            {
                //标识处理状态为成功,并停止计时
                token.ExecuteSuccess = true;
                token.Watch.Stop();
                await AddLog(token);


                token.LatestRunning = DateTime.UtcNow;

                var responseBytes = UTF8Encoding.UTF8.GetBytes(_emptyResponse);

                e.SetBuffer(responseBytes, 0, responseBytes.Length);

                willRaiseEvent = e.AcceptSocket.SendAsync(e);
                if (!willRaiseEvent)
                {
                    await ProcessSend(e);
                }

                return;
            }

            //如果收到的是空字节,表示客户端已经关闭,服务端也需要关闭
            if (token.RetrieveBytes.Count == 0)
            {
                lock (token.LockObj)
                {
                    token.Status = -1;
                }
                token.ReleaseReceiveSemaphore();
                return;
            }

            if (!_tcpDataExecuteFactories.TryGetValue(_listener.ExecuteDataFactoryType, out IFactory <ITcpDataExecute> tcpDataExecuteFactory))
            {
                lock (_tcpDataExecuteFactories)
                {
                    Type tcpDataExecuteFactoryType = Type.GetType(_listener.ExecuteDataFactoryType);

                    if (!_tcpDataExecuteFactories.TryGetValue(_listener.ExecuteDataFactoryType, out tcpDataExecuteFactory))
                    {
                        object objTcpDataExecuteFactory;
                        if (_listener.ExecuteDataFactoryTypeUseDI == true)
                        {
                            //通过DI容器创建
                            objTcpDataExecuteFactory = DIContainerContainer.Get(tcpDataExecuteFactoryType);
                        }
                        else
                        {
                            //通过反射创建
                            objTcpDataExecuteFactory = tcpDataExecuteFactoryType.Assembly.CreateInstance(tcpDataExecuteFactoryType.FullName);
                        }

                        if (!(objTcpDataExecuteFactory is IFactory <ITcpDataExecute>))
                        {
                            var fragment = new TextFragment()
                            {
                                Code = TextCodes.TcpDataExecuteTypeError,
                                DefaultFormatting = "Tcp监听{0}中,数据处理的工厂类型{1}未实现接口IFactory<ITcpDataExecute>",
                                ReplaceParameters = new List <object>()
                                {
                                    _listener.Name, _listener.ExecuteDataFactoryType
                                }
                            };

                            throw new UtilityException((int)Errors.TcpDataExecuteTypeError, fragment);
                        }

                        tcpDataExecuteFactory = (IFactory <ITcpDataExecute>)objTcpDataExecuteFactory;
                        _tcpDataExecuteFactories.Add(_listener.ExecuteDataFactoryType, tcpDataExecuteFactory);
                    }
                }
            }

            var tcpDataExecute = tcpDataExecuteFactory.Create();

            var byteResult = await tcpDataExecute.Execute(token.RetrieveBytes.ToArray());

            //标识处理状态为成功,并停止计时
            token.ExecuteSuccess = true;
            token.Watch.Stop();

            if (byteResult != null)
            {
                token.ResponseBytes = byteResult.ToList();
            }

            await AddLog(token);

            //发送返回值

            if (byteResult != null)
            {
                /*var bytes = UTF8Encoding.UTF8.GetBytes(strResult);
                 *
                 * var totalByteList = bytes.Length.ToBytes().ToList();
                 *
                 * totalByteList.AddRange(bytes);
                 *
                 * var totalBytes = totalByteList.ToArray();*/

                e.SetBuffer(byteResult, 0, byteResult.Length);
            }
            else
            {
                var responseBytes = UTF8Encoding.UTF8.GetBytes(_emptyResponse);
                e.SetBuffer(responseBytes, 0, responseBytes.Length);
            }


            willRaiseEvent = e.AcceptSocket.SendAsync(e);
            if (!willRaiseEvent)
            {
                await ProcessSend(e);
            }
        }
Exemple #6
0
        /// <summary>
        /// 数据接收处理
        /// </summary>
        /// <param name="e"></param>
        private async Task ProcessReceive(SocketAsyncEventArgs e)
        {
            TcpAcceptContext token = (TcpAcceptContext)e.UserToken;



            //从开始接受数据计时,默认执行状态设置为false
            token.ExecuteSuccess  = false;
            token.ExecuteError    = string.Empty;
            token.RequestDateTime = DateTime.UtcNow;
            token.Watch           = new Stopwatch();
            token.Watch.Start();



            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                //判断是否已经处于关闭状态,是,直接关闭,否,将状态改为正在处理
                bool needClose = false;
                lock (token.LockObj)
                {
                    if (token.Status == -1)
                    {
                        needClose = true;
                    }
                    else
                    {
                        token.Status        = 2;
                        token.LatestRunning = DateTime.UtcNow;
                    }
                }

                if (needClose)
                {
                    token.ReleaseReceiveSemaphore();
                    return;
                }

                var t = Task.Run(async() =>
                {
                    try
                    {
                        await DoProcessReceive(e);
                    }
                    catch (Exception ex)
                    {
                        token.ExecuteError = $"error message:{ex.Message},stack:{ex.StackTrace}";
                        token.Watch.Stop();
                        lock (token.LockObj)
                        {
                            token.Status = -1;
                        }
                        await AddLog(token);
                        token.ReleaseReceiveSemaphore();
                    }
                }
                                 );
            }
            else
            {
                lock (token.LockObj)
                {
                    token.Status = -1;
                }
                token.ReleaseReceiveSemaphore();
            }

            await Task.FromResult(0);
        }
Exemple #7
0
        /// <summary>
        /// 连接处理
        /// </summary>
        /// <param name="e"></param>
        private async Task ProcessAccept(SocketAsyncEventArgs e)
        {
            TcpAcceptContext token = (TcpAcceptContext)e.UserToken;

            ReleaseAcceptSemaphore();

            if (e.SocketError == SocketError.Success)
            {
                lock (token.LockObj)
                {
                    token.Status        = 1;
                    token.LatestRunning = DateTime.UtcNow;
                }


                while (true)
                {
                    await token.ReceiveSemaphore.WaitAsync();

                    //判断是否已经处于关闭状态
                    bool needClose = false;
                    lock (token.LockObj)
                    {
                        if (token.Status == -1)
                        {
                            needClose = true;
                        }
                    }

                    if (needClose)
                    {
                        CloseClientSocket(e);
                        break;
                    }

                    //重新初始化接收参数
                    token.RetrieveBytes = new List <byte>();

                    //设置缓冲区最大字节数
                    var    bufferCount = _listener.MaxBufferCount;
                    byte[] buffer      = new byte[bufferCount];

                    e.SetBuffer(buffer, 0, bufferCount);

                    try
                    {
                        bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(e);
                        if (!willRaiseEvent)
                        {
                            await ProcessReceive(e);
                        }
                    }
                    catch (Exception ex)
                    {
                        CloseClientSocket(e);
                        await AddLog($"ProcessAccept Error,message:{ex.Message},stack:{ex.StackTrace}", DateTime.UtcNow);

                        LoggerHelper.LogError(LogCategoryName, $"TcpListener {_listener.Name},ProcessAccept Error,message:{ex.Message},stack:{ex.StackTrace}");
                        break;
                    }
                }
            }
            else
            {
                //await AddLog($"ProcessAccept Error", DateTime.UtcNow);
                //LoggerHelper.LogError(_loggerFactory, LogCategoryName, $"TcpListener {_listener.Name},ProcessAccept Error");
                CloseClientSocket(e);
            }
        }
Exemple #8
0
        public async Task Start(TcpListener listener)
        {
            _listener = listener;
            if (!_start)
            {
                //设置监听Socket
                IPEndPoint localPoint = new IPEndPoint(IPAddress.Any, listener.Port);
                _listenSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
                _listenSocket.Bind(localPoint);
                _listenSocket.Listen(listener.MaxConcurrencyCount);


                //设置连接参数池
                _tcpAcceptContextPool = new Pool <TcpAcceptContext>($"TcpListener-{listener.Name}-AcceptContexts",
                                                                    null,
                                                                    null,
                                                                    null,
                                                                    null,
                                                                    async() =>
                {
                    var context = new TcpAcceptContext()
                    {
                        ListenSocket = _listenSocket
                    };

                    var acceptEventArg = new SocketAsyncEventArgs()
                    {
                        UserToken = context
                    };
                    acceptEventArg.Completed    += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                    context.SocketAsyncEventArgs = acceptEventArg;

                    return(await Task.FromResult(context));
                },
                                                                    async(item) =>
                {
                    return(await Task.FromResult(true));
                },
                                                                    null,
                                                                    null
                                                                    , listener.MaxConcurrencyCount);


                _start = true;



                if (_listener.KeepAlive)
                {
                    //启动定时检查Tcp连接
                    var t = Task.Run(async() =>
                    {
                        while (_start)
                        {
                            try
                            {
                                await ValidateConnection();
                            }
                            catch (Exception ex)
                            {
                                LoggerHelper.LogError(LogCategoryName, $"TcpListener {_listener.Name},ValidateConnection Error,message:{ex.Message},stack:{ex.StackTrace}");
                            }

                            System.Threading.Thread.Sleep(100);
                        }
                    });
                }

                await StartAccept(_listenSocket);
            }
        }