Console方式的通信服務

Console方式的通信服務

 

        好久沒有采用Console方式寫程序了,以前做項目如果用C++,也多采用MFC ,WTL等一些界面框架來做,記得用Console來做應用還是在剛畢業那會兒用C++寫寫演示程序什麼的,僅供學習之用了。最近採用C++寫了一個校園RFID信息接入的一個接口服務器,通過RFID接收設備獲取掃描到的RFID卡信息,然後上傳到數據庫,供上層應用來使用。系統的結構大致如下面這個圖。

RFID接收設備採用UDP報文上傳掃描到的RFID卡信息;

Socket庫初始化如下:

   int nRetCode = 0 ; 

    WSADATA wsaData ;

    WORD wVersionRequested = MAKEWORD( 1, 1 );    

    int err = WSAStartup( wVersionRequested, &wsaData );

    if ( err != 0 ) {

        return 0 ;

    }

    if ( LOBYTE( wsaData.wVersion ) != 1 ||

        HIBYTE( wsaData.wVersion ) != 1 ) {

            WSACleanup( );

            return 0 ;

    }

Socket初始化,綁定UDP端口

   _sockSrv=socket(AF_INET,SOCK_DGRAM,0); 

   SOCKADDR_IN addrSrv;

   addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

   addrSrv.sin_family=AF_INET;

   addrSrv.sin_port=htons(32500);

   bind(_sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

然後啓動一個單獨的線程接收UDP報文

   _hThread = CreateThread( NULL , NULL , ProcessRFID , &_sockSrv ,NULL , &dwThread ) ;

線程函數處理接收數據,判斷有效性,並處理接收到的報文

   SOCKET sockSrv = *(SOCKET *)lpVoid ;

   UCHAR   buffer[MAX_BUFFER] = {0} ;   

   SOCKADDR_IN addrClient;

   int addrLen=sizeof(SOCKADDR);

   while(1)

   {

            int iLen = recvfrom( sockSrv ,(CHAR *)buffer , MAX_BUFFER , 0 , (sockaddr *)&addrClient , &addrLen ) ;              

            if( iLen == 0 || iLen == SOCKET_ERROR)

            {

                     return -1;

            }

            //////////////////////////////////////////////////////////////////////////

            //解析報文開始

            if( !ValidRFidPacket(buffer , iLen ))

            {

                return -1 ;

            }

           HandleRFidPacket(buffer , iLen ) ;

   }

這裏注意,當關閉Console窗口的時候,需要後續的清理動作

所以在初始化的時候,還需要補充設置一下事件回調

SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) ;

回調函數內容調用ExitProcess做退出清理

BOOL CtrlHandler( DWORD fdwCtrlType )

{

    switch( fdwCtrlType )

    {

    case CTRL_CLOSE_EVENT:

        ExitProcess() ;

        return( TRUE );

 

    case CTRL_LOGOFF_EVENT:

        ExitProcess() ;       

        return FALSE;

    case CTRL_SHUTDOWN_EVENT:

        ExitProcess() ;

        return FALSE;

    default:

        return FALSE;

    }

}

運行後截圖

採用Console方式做的通信服務器,信息查看採用命令行就行了,界面不需要耗費過多的資源,運行還是比較穩定的。運行起來佔用的內存基本不會有變化,長時間運行性能更穩定。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章