예제 #1
0
 protected override void OnConnectServer()
 {
     //Send handshake message block to build secure connection like SSL
     base.Send(new MessageBlock(MessageBlockType.Handshake, (int)HandshakeType.ClientHello));
     Session.Handshake = HandshakeType.ClientHello;
     NetDebuger.PrintDebugMessage(Session, "SEND ClientHello");
 }
예제 #2
0
        /// <summary>
        /// 停止服务器
        /// </summary>
        protected override void OnStop()
        {
            base.OnStop(); // 关闭心跳检查功能

            lock (Sessions) {
                TSession[] array = Sessions.ToArray();

                foreach (TSession session in array)
                {
                    CloseSession(session);
                }

                Sessions.Clear();
            }

            try {
                Socket.Close();
            }
            catch (ObjectDisposedException)
            {
                //服务器套接字已经关闭
            }

            NetDebuger.PrintDebugMessage(this.GetType().Name + " Stop, clear resource success");
        }
예제 #3
0
 /// <summary>
 /// 启动心跳检查功能
 /// </summary>
 protected override void OnStart()
 {
     if (EnableCheckHeartBeat)
     {
         checkTimer = new Timer(new TimerCallback(CheckHeartBeatCallBack), null,
                                HeartBeatPeriod, HeartBeatPeriod);
         NetDebuger.PrintDebugMessage("Start heartbeat checker, Period:" + HeartBeatPeriod + "(ms)");
     }
 }
예제 #4
0
        /// <summary>
        /// 通讯错误事件
        /// </summary>
        /// <param name="session"></param>
        /// <param name="e"></param>
        internal protected virtual void ReportError(TSession session, Exception e)
        {
            if (e is SocketException)
            {
                SocketException se  = e as SocketException;
                string          msg = string.Format("SocketException Code:{0}, Native Code:{1}", se.ErrorCode, se.NativeErrorCode);
                NetDebuger.PrintErrorMessage(session, msg);
            }

            NetDebuger.PrintErrorMessage(session, e.ToString());
        }
예제 #5
0
        /// <summary>
        /// 检查Session是否还在活动
        /// </summary>
        /// <param name="timeOut">超时时间(ms)</param>
        /// <returns>正在活动返回true,否则返回false</returns>
        public virtual bool IsActive(int timeOut)
        {
            NetDebuger.PrintDebugMessage(this, string.Format("TimeOut:{0}-Period:{1}", timeOut, TimeCounter.Milliseconds));

            if (timeOut < TimeCounter.Milliseconds)
            {
                return(false);
            }

            return(true);
        }
예제 #6
0
 /// <summary>
 /// Sessions the on received message block.
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="e">The e.</param>
 private void SessionOnReceivedMessageBlock(object sender, MessageBlockArgs e)
 {
     if (e.MessageBlock.Type == MessageBlockType.HeartBeat && EnableCheckHeartBeat)
     {
         Session.TimeCounter.Reset(); //Refresh the heart Beat timer
         NetDebuger.PrintDebugMessage(Session, "Recv server heart Beat");
     }
     else
     {
         OnReceivedMessageBlock(e.MessageBlock);
     }
 }
예제 #7
0
        /// <summary>
        /// 启动服务器,监听客户端连接
        /// </summary>
        protected override void OnStart()
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint iep = new IPEndPoint(IPAddress.Any, Port);

            socket.Bind(iep);

            socket.Listen(100);
            WaitForClient(); //等待客户端连接
            NetDebuger.PrintDebugMessage(
                string.Format("{0} is running, listen port:{1} and capacity:{2}", this.GetType().Name, Port, Capacity));
            base.OnStart(); //启动心跳检查功能
        }
예제 #8
0
 /// <summary>
 /// 关闭会话,把会话从服务器中移除
 /// </summary>
 /// <param name="session">需要关闭的Session</param>
 protected virtual void CloseSession(TSession session)
 {
     lock (Sessions) {
         if (Sessions.Contains(session))
         {
             Sessions.Remove(session);
             NetDebuger.PrintDebugMessage(session, "Close");
             NetDebuger.PrintDebugMessage(session, string.Format("Remove:{0}/{1}", SessionsCount, Capacity));
             OnCloseSession(session); //关闭前调用
             session.Close();
         }
     }
 }
예제 #9
0
        /// <summary>
        /// 异步Socket中的接收新连接回调函数
        /// </summary>
        /// <param name="parameter"></param>
        private void AcceptCallback(IAsyncResult parameter)
        {
            TSession session = default(TSession);

            try {
                // 创建新连接
                session = CreateSession(socket.EndAccept(parameter));

                if (!Full)
                {
                    lock (Sessions) {
                        Sessions.Add(session);
                    }

                    // 调用客户端生成函数,检查是否为合格的客户端
                    if (!OnCreateSession(session))
                    {
                        session.Close();
                        return;
                    }

                    // 开始注册客户端数据接收事件
                    session.OnReceivedData += new EventHandler <DataBlockArgs>(SessionReceivedData);
                    // 开始接收客户端数据
                    WaitForData(session);

                    NetDebuger.PrintDebugMessage(session, "Create");
                    NetDebuger.PrintDebugMessage(session, string.Format("Add:{0}/{1}", SessionsCount, Capacity));
                }
                else
                {
                    OnServerFull(session);
                    NetDebuger.PrintDebugMessage(session, "Server full");
                    session.Close();
                }
            }
            catch (ObjectDisposedException)
            {
                // 监听的Socket已经关闭
            }
            catch (SocketException e)
            {
                HandleSocketException(session, e);

                CloseSession(session); // 接收数据发送错误,需要关闭该Socket
            }
            finally
            {
                WaitForClient();// 继续接收客户端连接
            }
        }
예제 #10
0
 /// <summary>
 /// 停止检查心跳功能
 /// </summary>
 protected override void OnStop()
 {
     if (EnableCheckHeartBeat && checkTimer != null)
     {
         lock (checkTimer) {
             if (EnableCheckHeartBeat && checkTimer != null)
             {
                 NetDebuger.PrintDebugMessage("Stop heartbeat checker");
                 checkTimer.Dispose();
                 checkTimer = null;
             }
         }
     }
 }
예제 #11
0
 protected virtual void StartHeartBeat()
 {
     /*如果EnableCheckHeartBeat=true,会启动心跳检查,这样就不能调用基类的OnStart()函数
      * 服务器设定一个心跳超时时间,客户端检查超时的时间应该与此一致。客户端程序会在该时间
      * 的二分之一时间内,发送一个心跳包,服务器会返回一个心跳包,这样客户端就能够知道服务器是否能够正确的响应。
      */
     if (EnableCheckHeartBeat)
     {
         checkTimer = new Timer(new TimerCallback(CheckHeartBeatCallBack), null,
                                HeartBeatPeriod / 2, HeartBeatPeriod / 2);
         NetDebuger.PrintDebugMessage("Start heart Beat checker, Period:" + HeartBeatPeriod + "(ms)");
         Session.TimeCounter.Start();
     }
 }
예제 #12
0
        /// <summary>
        /// 检查心跳的回调函数
        /// </summary>
        /// <param name="o">参数(未使用)</param>
        protected override void CheckHeartBeatCallBack(object o)
        {
            //If client is on line, go on send heart Beat singal
            if (IsConnected)
            {
                base.CheckHeartBeatCallBack(o);
            }

            if (IsConnected)//如果没有掉线,继续发送心跳信号
            {
                MessageBlock heartBeatMB = new MessageBlock(MessageBlockType.HeartBeat);
                Send(heartBeatMB);
                NetDebuger.PrintDebugMessage(Session, "Send Heart Beat");
            }
        }
예제 #13
0
        /// <summary>
        /// Sessions the on received message block.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The e.</param>
        private void SessionOnReceivedMessageBlock(object sender, MessageBlockArgs e)
        {
            if (EnableCheckHeartBeat)
            {
                if (e.MessageBlock.Type == MessageBlockType.HeartBeat)
                {
                    TSession session = (TSession)sender;
                    //Todo:多线程安全
                    session.TimeCounter.Reset(); //定时器开始新的计时
                    Send(session, e.MessageBlock);
                    NetDebuger.PrintDebugMessage(session, "Heartbeat");
                    return;
                }
            }

            OnReceivedMessageBlock((TSession)sender, e.MessageBlock);
        }
예제 #14
0
        /// <summary>
        /// 启动心跳检查功能
        /// </summary>
        protected override void OnStart()
        {
            IPAddress[] hostIPAddress = Dns.GetHostAddresses(Host);

            if (hostIPAddress.Length == 0)
            {
                throw new NetException("Get host ddress fail");
            }

            isConnected = false;
            sendQueue.Clear();
            IPEndPoint iep = new IPEndPoint(hostIPAddress[0], Port);

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            Socket.BeginConnect(iep, ConnectCallBack, null);
            serverIP = hostIPAddress[0].ToString();

            NetDebuger.PrintDebugMessage(string.Format("Connecting server:{0}:{1}...", serverIP.ToString(), port));
        }
예제 #15
0
        /// <summary>
        /// 心跳检查回调函数
        /// </summary>
        /// <param name="para"></param>
        protected override void CheckHeartBeatCallBack(object para)
        {
            List <TSession> closeSessions = new List <TSession>();

            lock (Sessions) {
                foreach (TSession session in Sessions)
                {
                    if (!session.IsActive(HeartBeatPeriod))   // todo:是否需要修改到服务器方法
                    {
                        closeSessions.Add(session);
                        NetDebuger.PrintDebugMessage(session, "Heartbeat is timeout and add it to closing list");
                    }
                }
            }

            foreach (TSession session in closeSessions)
            {
                CloseSession(session);
            }
        }
예제 #16
0
 /// <summary>
 /// Called when [received command].
 /// </summary>
 /// <param name="session">The session.</param>
 /// <param name="command">The command.</param>
 protected virtual void OnReceivedCommand(TSession session, string command)
 {
     NetDebuger.PrintDebugMessage(session, command);
 }
예제 #17
0
        private void HandleHandshake(TSession session, HandshakeType handshakeType, MessageBlock mb)
        {
            switch (handshakeType)
            {
            case HandshakeType.ClientHello:
            {
                MessageBlock mb1 = new MessageBlock(MessageBlockType.Handshake,
                                                    (int)HandshakeType.ServerHello);
                base.Send(session, mb1);
                session.Handshake = HandshakeType.ServerHello;

                NetDebuger.PrintDebugMessage(session, "ClientHello");
                break;
            }

            case HandshakeType.ClientKeyExchange:
            {
                session.CheckPrePhase(HandshakeType.ServerHello);
                session.RemotePublicKey = Encoding.Unicode.GetString(mb.Body.Buffer);

                NetDebuger.PrintDebugMessage(session, "Client Public Key:" + session.RemotePublicKey);

                MessageBlock mb2 = new MessageBlock(
                    MessageBlockType.Handshake,
                    (int)HandshakeType.ServerKeyExchange,
                    new DataBlock(Encoding.Unicode.GetBytes(key.PublicKey)));

                base.Send(session, mb2);
                session.Handshake = HandshakeType.ServerKeyExchange;
                NetDebuger.PrintDebugMessage(session, "ClientKeyExchange");
                break;
            }

            case HandshakeType.ClientSymmetricKey:
            {
                session.CheckPrePhase(HandshakeType.ServerKeyExchange);
                byte[] key = Singleton <RSACryptServiceBase> .Instance.Decrypt(
                    mb.Body.Buffer, this.key.XmlString);

                session.SymmetricCryptService.SA.Key = key;

                NetDebuger.PrintDebugMessage(session, "Client SA Key:" + Convert.ToBase64String(key));

                MessageBlock getKeymb = new MessageBlock(MessageBlockType.Handshake,
                                                         (int)HandshakeType.ServerGetSymmetricKey);
                base.Send(session, getKeymb);

                session.Handshake = HandshakeType.ServerGetSymmetricKey;
                NetDebuger.PrintDebugMessage(session, "ClientSymmetrickey");
                break;
            }

            case HandshakeType.ClientSymmetricIV:
            {
                session.CheckPrePhase(HandshakeType.ServerGetSymmetricKey);
                byte[] iv = Singleton <RSACryptServiceBase> .Instance.Decrypt(
                    mb.Body.Buffer, this.key.XmlString);

                session.SymmetricCryptService.SA.IV = iv;

                NetDebuger.PrintDebugMessage(session, "Client SA IV:" + Convert.ToBase64String(iv));

                MessageBlock getIVmb = new MessageBlock(MessageBlockType.Handshake,
                                                        (int)HandshakeType.ServerGetSymmetricIV);
                base.Send(session, getIVmb);

                session.Handshake = HandshakeType.ServerGetSymmetricIV;
                NetDebuger.PrintDebugMessage(session, "ClientSymmetricIV");
                break;
            }

            case HandshakeType.ClientFinished:
            {
                session.CheckPrePhase(HandshakeType.ServerGetSymmetricIV);
                MessageBlock mb3 = new MessageBlock(MessageBlockType.Handshake,
                                                    (int)HandshakeType.ServerFinished);
                base.Send(session, mb3);
                session.Handshake = HandshakeType.OK;
                NetDebuger.PrintDebugMessage(session, "Client Handshake Finished");
                OnBuildDataConnection(session);
                NetDebuger.PrintDebugMessage(session, "Build security community channel");
                break;
            }
            }
        }
예제 #18
0
        private void HandleHandshakeType(HandshakeType type, MessageBlock mb)
        {
            switch (type)
            {
            case HandshakeType.ServerHello:
            {
                NetDebuger.PrintDebugMessage(Session, "RECV ServerHello");

                Session.CheckPrePhase(HandshakeType.ClientHello);

                MessageBlock mb1 = new MessageBlock(MessageBlockType.Handshake,
                                                    (int)HandshakeType.ClientKeyExchange,
                                                    new DataBlock(Encoding.Unicode.GetBytes(key.PublicKey)));
                base.Send(mb1);
                Session.Handshake = HandshakeType.ClientKeyExchange;
                NetDebuger.PrintDebugMessage(Session, "SEND ClientKeyExchange");
            }
            break;

            case HandshakeType.ServerKeyExchange:
            {
                NetDebuger.PrintDebugMessage(Session, "RECV ServerKeyExchange");
                Session.CheckPrePhase(HandshakeType.ClientKeyExchange);
                Session.RemotePublicKey = Encoding.Unicode.GetString(mb.Body.Buffer);
                //Get Crypt key data
                byte[] keyData = Singleton <RSACryptServiceBase> .Instance.Encrypt
                                     (Session.SymmetricCryptService.SA.Key, Session.RemotePublicKey);

                //Send Client Symmetric key
                MessageBlock skmb = new MessageBlock(MessageBlockType.Handshake,
                                                     (int)HandshakeType.ClientSymmetricKey,
                                                     new DataBlock(keyData));
                base.Send(skmb);

                Session.Handshake = HandshakeType.ClientSymmetricKey;
                NetDebuger.PrintDebugMessage(Session, "SEND ClientSymmetricKey");
            }
            break;

            case HandshakeType.ServerGetSymmetricKey:
            {
                NetDebuger.PrintDebugMessage(Session, "RECV ServerGetSymmetrickey");

                Session.CheckPrePhase(HandshakeType.ClientSymmetricKey);
                //Get crypt iv data
                byte[] ivData = Singleton <RSACryptServiceBase> .Instance.Encrypt(
                    Session.SymmetricCryptService.SA.IV, Session.RemotePublicKey);

                //Send Client Symmetric IV
                MessageBlock ivmb = new MessageBlock(MessageBlockType.Handshake,
                                                     (int)HandshakeType.ClientSymmetricIV,
                                                     new DataBlock(ivData));
                base.Send(ivmb);
                Session.Handshake = HandshakeType.ClientSymmetricIV;
                NetDebuger.PrintDebugMessage(Session, "SEND ClientSymmetricIV");
            }
            break;

            case HandshakeType.ServerGetSymmetricIV:
            {
                NetDebuger.PrintDebugMessage(Session, "RECV ServerGetSymmetricIV");

                Session.CheckPrePhase(HandshakeType.ClientSymmetricIV);
                MessageBlock mb2 = new MessageBlock(MessageBlockType.Handshake,
                                                    (int)HandshakeType.ClientFinished);
                base.Send(mb2);
                Session.Handshake = HandshakeType.ClientFinished;
                NetDebuger.PrintDebugMessage(Session, "SEND ClientFinished");
                break;
            }

            case HandshakeType.ServerFinished:
            {
                Session.CheckPrePhase(HandshakeType.ClientFinished);
                Session.Handshake = HandshakeType.OK;
                NetDebuger.PrintDebugMessage(Session, "RECV ServerFinished. OK!");
                isConnected = true;
                StartHeartBeat();

                //为了继续接收新数据,需要立刻返回,
                //所以需要从新进程中调用OnBuildDataConnection();
                buildConnThread = new Thread(OnBuildDataConnection);
                buildConnThread.Start();
            }
            break;
            }
        }