예제 #1
0
 public void Close()
 {
     try
     {
         if (!IsConnected)
         {
             return;
         }
         IsConnected = false;
         SessionContainer.Remove(SessionId);
         OnClosed?.Invoke(this);
         Socket?.Close();
     }
     catch (Exception ex)
     {
         LogHelper.Error($"关闭连接出错,{ex}");
     }
 }
예제 #2
0
        /// <summary>
        /// 接收数据回调
        /// </summary>
        /// <param name="state"></param>
        async void UdpReceiveCallback(IAsyncResult asyncResult)
        {
            //服务端的Socket实例
            var session = (TSession)asyncResult.AsyncState;
            //定义远程的计算机地址
            EndPoint remouteEP = new IPEndPoint(IPAddress.Any, 0);
            //接收到的数据长度
            var length = session.Socket.EndReceiveFrom(asyncResult, ref remouteEP);

            //记录远程主机
            session.RemoteEndPoint = remouteEP;
            //查找客户端集合是否已存在该远程主机,存在的话直接用缓存的Session
            var querySession = GetSingleSession(c => c.RemoteEndPoint.ToString() == session.RemoteEndPoint.ToString());

            if (querySession != null)
            {
                querySession.RemoteEndPoint = remouteEP;
                session = querySession;
            }
            else
            {
                Pipe pipe = new Pipe();
                session.Reader      = pipe.Reader;
                session.Writer      = pipe.Writer;
                session.IsConnected = true;
                ProcessReadAsync(session);
                //有可能是广播,添加到客户端集合
                SessionContainer.Add(session);
                OnConnected?.Invoke(session);
            }
            //读取到的数据
            var data = session.Data.CloneRange(0, length);
            //将收到的数据写入Pipe管道
            await session.Writer.WriteAsync(new Memory <byte>(data));

            //继续异步接收数据
            var nextSession = new TSession {
                Socket = Socket, LocalEndPoint = Socket.LocalEndPoint
            };

            session.Socket.BeginReceiveFrom(nextSession.Data, 0, nextSession.Data.Length, SocketFlags.None, ref remouteEP, UdpReceiveCallback, nextSession);
        }
예제 #3
0
        /// <summary>
        /// 启动服务
        /// </summary>
        /// <returns></returns>
        public virtual Task <bool> StartAysnc()
        {
            return(Task.Run(() =>
            {
                bool isSuccess = false;
                try
                {
                    if (ServerOption == null)
                    {
                        throw new ArgumentException("ServerOption服务配置尚未配置");
                    }
                    IPEndPoint iPEndPoint = new IPEndPoint(ServerOption.Ip == "Any" ? IPAddress.Any : IPAddress.Parse(ServerOption.Ip), ServerOption.Port);
                    if (ServerOption.ProtocolType == ProtocolType.Tcp)
                    {
                        #region TCP
                        Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
                        {
                            NoDelay = ServerOption.NoDelay
                        };
                        Socket.Bind(iPEndPoint);
                        //开始监听
                        Socket.Listen(ServerOption.BackLog);
                        //开启一个线程接收客户端连接
                        Task.Run(async() =>
                        {
                            while (true)
                            {
                                var client = await Socket.AcceptAsync();
                                //构造客户端Session
                                var session = new TSession
                                {
                                    Socket = client,

                                    LocalEndPoint = client.LocalEndPoint,
                                    RemoteEndPoint = client.RemoteEndPoint
                                };
                                //非SSL
                                if (ServerOption.Security == SslProtocols.None)
                                {
                                    //Socket转字节流对象
                                    session.Stream = new NetworkStream(session.Socket, true);
                                    //字节流绑定到Pipe管道(高性能缓冲区)
                                    session.Reader = PipeReader.Create(session.Stream); //读取数据端
                                    session.Writer = PipeWriter.Create(session.Stream); //发送数据端

                                    //添加到Session容器
                                    SessionContainer.Add(session);
                                    OnConnected?.Invoke(session);
                                    //开启一个线程异步接收这个连接的数据
                                    ProcessReadAsync(session);
                                }
                                else//SSL
                                {
                                    //绑定SSL认证回调
                                    ServerOption.SslServerAuthenticationOptions.RemoteCertificateValidationCallback = SSLValidationCallback;
                                    //加密传输字节流
                                    var sslStream = new SslStream(new NetworkStream(session.Socket, true), false);
                                    var cancelTokenSource = new CancellationTokenSource();
                                    //SSL认证超时时间为5s
                                    cancelTokenSource.CancelAfter(5000);
                                    await sslStream.AuthenticateAsServerAsync(ServerOption.SslServerAuthenticationOptions, cancelTokenSource.Token).ContinueWith(t =>
                                    {
                                        if (sslStream.IsAuthenticated)
                                        {
                                            //验证成功
                                            session.Stream = sslStream;
                                            //字节流绑定到Pipe管道(高性能缓冲区)
                                            session.Reader = PipeReader.Create(session.Stream); //读取数据端
                                            session.Writer = PipeWriter.Create(session.Stream); //发送数据端

                                            //添加到Session容器
                                            SessionContainer.Add(session);
                                            OnConnected?.Invoke(session);
                                            //开启一个线程异步接收这个连接的数据
                                            ProcessReadAsync(session);
                                        }
                                        else
                                        {
                                            if (t.IsCanceled)
                                            {
                                                LogHelper.Error($"连接{session.RemoteEndPoint}证书验证超时,关闭连接");
                                            }
                                            Close(session);
                                        }
                                    });
                                }
                            }
                        });
                        #endregion
                    }
                    else if (ServerOption.ProtocolType == ProtocolType.Udp)
                    {
                        #region UDP
                        Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                        Socket.Bind(iPEndPoint);
                        EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
                        var session = new TSession
                        {
                            Socket = Socket,
                            LocalEndPoint = Socket.LocalEndPoint
                        };
                        //异步接收这个连接的数据
                        Socket.BeginReceiveFrom(session.Data, 0, session.Data.Length, SocketFlags.None, ref remoteEP, UdpReceiveCallback, session);
                        #endregion
                    }
                    else
                    {
                        throw new Exception("不支持的传输协议");
                    }

                    isSuccess = true;
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"【{ServerOption.Port}】端口启动监听异常:{ex}");
                }

                return isSuccess;
            }));
        }