[セットトップ]C#高性能大容量SOCKET同時(六):タイムアウトSocket切断(デーモンスレッド)とハートビートパケット


デーモンスレッド
サービス・エンド・エディションのSocketプログラミングでは、長い間データを送信していないSocketを処理する必要があります.タイムアウトしてから接続を切断する必要があります.独立したスレッド(DaemonThread)でポーリングする必要があります.切断を実行するときは、Socketオブジェクトをロックし、CloseClientSocketを呼び出して接続を切断する必要があります.具体的な処理コードは次のとおりです.
namespace SocketAsyncSvr
{
    class DaemonThread : Object
    {
        private Thread m_thread;
        private AsyncSocketServer m_asyncSocketServer;

        public DaemonThread(AsyncSocketServer asyncSocketServer)
        {
            m_asyncSocketServer = asyncSocketServer;
            m_thread = new Thread(DaemonThreadStart);
            m_thread.Start();
        }

        public void DaemonThreadStart()
        {
            while (m_thread.IsAlive)
            {
                AsyncSocketUserToken[] userTokenArray = null;
                m_asyncSocketServer.AsyncSocketUserTokenList.CopyList(ref userTokenArray);
                for (int i = 0; i < userTokenArray.Length; i++)
                {
                    if (!m_thread.IsAlive)
                        break;
                    try
                    {
                        if ((DateTime.Now - userTokenArray[i].ActiveDateTime).Milliseconds > m_asyncSocketServer.SocketTimeOutMS) // Socket 
                        {
                            lock (userTokenArray[i])
                            {
                                m_asyncSocketServer.CloseClientSocket(userTokenArray[i]);
                            }
                        }
                    }                    
                    catch (Exception E)
                    {
                        Program.Logger.ErrorFormat("Daemon thread check timeout socket error, message: {0}", E.Message);
                        Program.Logger.Error(E.StackTrace);
                    }
                }

                for (int i = 0; i < 60 * 1000 / 10; i++) // 
                {
                    if (!m_thread.IsAlive)
                        break;
                    Thread.Sleep(10);
                }
            }
        }

        public void Close()
        {
            m_thread.Abort();
            m_thread.Join();
        }
    }
}

ハートビートパック
タイムアウト接続があり、それに対応してハートビートパケットを設計する必要があり、ハートビートパケットは接続とメンテナンスの接続状態を検出するために使用され、ハートビートパケットの原理はクライアントが1つのパケットをサーバーに送信し、サーバーが受け取った後に1つの応答パケットをクライアントに送信し、戻るかどうかを検出することによって接続が正常かどうかを判断し、ハートビートパケットはBaseSocketProtocolDoActiveメソッドにあります.
        public bool DoActive()
        {
            m_outgoingDataAssembler.AddSuccess();
            return DoSendResult();
        }

具体的には、制御プロトコルControlSocketProtocolが心拍プロトコルを実装するなど、各プロトコルによって呼び出されるかどうかが決定されます.
        public override bool ProcessCommand(byte[] buffer, int offset, int count) // , 
        {
            ControlSocketCommand command = StrToCommand(m_incomingDataParser.Command);
            m_outgoingDataAssembler.Clear();
            m_outgoingDataAssembler.AddResponse();
            m_outgoingDataAssembler.AddCommand(m_incomingDataParser.Command);
            if (!CheckLogined(command)) // 
            {
                m_outgoingDataAssembler.AddFailure(ProtocolCode.UserHasLogined, "");
                return DoSendResult();
            }
            if (command == ControlSocketCommand.Login)
                return DoLogin();
            else if (command == ControlSocketCommand.Active)
                return DoActive();
            else if (command == ControlSocketCommand.GetClients)
                return DoGetClients();
            else
            {
                Program.Logger.Error("Unknow command: " + m_incomingDataParser.Command);
                return false;
            }
        }

DEMOダウンロードアドレス:
http://download.csdn.net/detail/sqldebug_fan/7467745
免責声明:このコードは、C#がポートプログラミングを完了したことを示すために使用され、学習と研究にのみ使用され、ビジネス用途には使用されません.レベルが限られていて、C#も初学に属して、間違いは避けられないので、指摘と指導を歓迎します.メールアドレス:[email protected].