LoginGate
ˣ
 
1ȴLoginGate.cpp WinMain
    1) CheckAvailableIOCP : ǲNT2000ϵͳIOCP
    2) InitInstance: ʼ棬WSAStartup
3)  MainWndProcڻص.
2MainWndProc.CPPзصMainWndProc
switch (nMsg)
    {
        case _IDM_CLIENTSOCK_MSG:
        case WM_COMMAND:
        case WM_CLOSE
    g_ssock Local    7000 Ϸ½˿
g_csock Remote   5000 ͵logsrvϵ׽
1_IDM_CLIENTSOCK_MSG ϢlogsrvصͨѶ¼
ãOnClientSockMsg,úһص
             ֮ConnectToServer(_IDM_CLIENTSOCK_MSGϢ FD_CONNECT|FD_READ|FD_CLOSE)WSAAsyncSelecthWndھӦĴWindowsϢʽ¼֪ͨOnClientSockMsgҪlogsrv֮ͨţתͻݰȣ 
switch (WSAGETSELECTEVENT(lParam))
   {
       case FD_CONNECT:
       case FD_CLOSE:
       case FD_READ: 
 
FD_CONNECT()
  A. CheckSocketErrorʱ
a). ConnectToServerڷʱִһΡص
FD_CONNECT
   b)logsrvʱ,ThreadFuncForMsg̣߳Ѵӿͻ˷͵(g_xMsgQueue, FD_READ¼logSrv) ͶI/OIOCPģͣ͵ͻˡSleepEx̡߳һI/O ɻصá һ첽̵Ŷӵ̡߳ 
ThreadFuncForMsg̼߳(logSrvյg_xMsgQueueݰ-)i/o ͶݣIOCP͸ͻˡ
        if (nSocket = AnsiStrToVal(pszFirst + 1)) //õsocket
       WSASend((SOCKET)nSocket, &Buf, 1, &dwSendBytes, 0, NULL, 
 
c)ֹʱ_ID_TIMER_CONNECTSERVER
KillTimer(g_hMainWnd, _ID_TIMER_CONNECTSERVER);
d)_ID_TIMER_KEEPALIVEʱ ݰ
SetTimer(g_hMainWnd, _ID_TIMER_KEEPALIVE
     öʱصOnTimerProc: ʱݰlogsrvSendExToServer(PACKET_KEEPALIVE);
 
B. socketϿ_ID_TIMER_CONNECTSERVERʱ
ConnectToServerӷ
                   _ID_TIMER_CONNECTSERVER, (TIMERPROC)OnTimerProc);
              FD_CLOSE:
                     ϿlogsrvSOCKETӣOnCommand(IDM_STOPSERVICE, 0); صIDM_STOPSERVICE
              FD_READ:
                     logsrv͵ݰ,½֤selCurַݼ뻺(g_xMsgQueue)С
 
2WM_COMMAND:
          IDM_STARTSERVICE: (IOCPģServerӦͻ)
          IDM_STOPSERVICE: ֹͣ(IOCPģServer)
    3WM_CLOSE:
          IDM_STOPSERVICE: ֹͣ(IOCPģServer)
          WSACleanup();
PostQuitMessage(0); //WM_DESTROYϢ
 
IDM_STARTSERVICE: (IOCPģServerӦͻ)
InitServerSocket
1) AcceptThreaḍ߳
      Accept֮һCSessionInfopNewUserInfo->sock = Accept; ͻSocketֵֵṹ塣¼ͻϢ
µ׽־CreateIoCompletionPortɶ˿ڣȻ󷢳һ첽WSASendWSARecv(pNewUserInfo->Recv();տͻϢ)Ϊ첽WSASend/WSARecvϷأʵʵķͻ߽ݵĲWINDOWSϵͳȥȻCSessionInfog_xSessionListСlogsrvûSessionϢ%0socket/ip$\0          
     ڿͻaccept֮ͶһI/O(recv),ȻӦݷlogsrv
 
   2) CreateIOCPWorkerThread
          CreateIoCompletionPort ݴһServerWorkerThread̡߳
ServerWorkerThread̹߳ԭ
ѭGetQueuedCompletionStatus()õIOWINDOWSϵͳWSASendWSArecvĲѽɶ˿ڡGetQueuedCompletionStatus()Ϸ,ɶ˿ȡøɵWSASend/WSARecvĽȻŷWSASend/WSARecvһѭGetQueuedCompletionStatus()
a). pSessionInfoΪջdwBytesTransferred =0 ,ڿͻclose socketӦݰ(쳣logsrv(X-ݰ)رտͻװ֡
         b). while ( pSessionInfo->HasCompletionPacket() ) ֤ȷתݰ(A-ݰ) logsrv
 c). if (pSessionInfo->Recv() ͶI/O
      ܽ᣺
ǲͣط첽WSASend/WSARecv IOIOWINDOWSϵͳɣWINDOWSϵͳʵʵIO󣬰ѽ͵ɶ˿ϣжIOˣôɶ˿ųһУһ߳ɶ˿ڲϵȡIOȻҪٷWSASend/WSARecv IO
 
IDM_STOPSERVICE: ֹͣ(IOCPģServerӦͻ)
   Close -> OnCommand(IDM_STOPSERVICE, 0L); ->g_fTerminated = TRUE; ߳˳
    if (g_hAcceptThread != INVALID_HANDLE_VALUE)
    {
        TerminateThread(g_hAcceptThread, 0);
         WaitForSingleObject(g_hAcceptThread, INFINITE); //IOCPAccept߳
         CloseHandle(g_hAcceptThread);
         g_hAcceptThread = INVALID_HANDLE_VALUE;
     }
 
     if (g_hMsgThread != INVALID_HANDLE_VALUE)
     {
         TerminateThread(g_hMsgThread, 0); //¼ص߳
         WaitForSingleObject(g_hMsgThread, INFINITE);
         CloseHandle(g_hMsgThread);
         g_hMsgThread = INVALID_HANDLE_VALUE;
     }
     ClearSocket(g_ssock);
     ClearSocket(g_csock);
     CloseHandle(g_hIOCP);
 
ܽ᣺
LoginGate¼طܿͻӣҰûIDֱӷ͵LoginSvrУLoginSrv֤֮󣬷ݰظͻˡLoginGate֮ͨʱʱ͡ݡ֤ġͻ˵ڴУǽйܵġ
loginSrv͡%A+Msg+$0Ϣ תͻϢ
                 %X+Msg+$0Ϣ ûϢӵûб
                 %O+Msg+$0Ϣ ûϢ
 
 
 
Ҫ̣
LoginGateAcceptThread,ServerWorkerThreaḍ߳AcceptThread߳̽տͻӣsessionϢ͸loginSrvServerWorkerThread̴߳ɶ˿ȡøɵWSASend/WSARecvĽ󣬰ѿͻתloginSrvʱWSAAsyncSelectģӵloginSrvСһӳɹThreadFuncForMsg̴̣߳߳g_xMsgQueue(FD_READ¼loginSrv)ȡloginSrvݡͶI/OIOCPģͣ͵ͻˡ
ServerWorkerThreadתͻ -> WSAAsyncSelectReadloginSrv󷵻ص-> ThreadFuncForMsg̣߳ͶWSASendϢWindowsIOCPݸͻˡ
