xuejianhui

导航

初解禁:SDK服务端主程序入口函数SDK服务端主程序入口函数

/********************************************************************
函 数 名:        main
功能描述:      SDK服务端主程序入口函数SDK服务端主程序入口函数
返 回 值:        成功返回RESULT_SUCCESS,失败返回RESULT_FAIL
********************************************************************/
INT main()
{
    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_NOTICE, g_enDebugFlag, "1. Enter SDK Server Main Function and set rlimit!");

    if(SIG_ERR == signal(SIGTERM, ExitProcess))
    {
        WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NOTICE, g_enDebugFlag, "signal func error!");
        exit(0);
    }

    struct epoll_event evEpoll;
    struct epoll_event evEpollEvents[EPOLL_MAX_EVENT];
    struct rlimit rtSdk;
    memset(&evEpoll, 0x00, sizeof(struct epoll_event));
    memset(evEpollEvents, 0x00, sizeof(struct epoll_event) * EPOLL_MAX_EVENT);
    memset(&rtSdk, 0x00, sizeof(struct rlimit));

    /* 1.设置进程允许打开的最大文件数为EPOLL_MAX_EVENT */
    rtSdk.rlim_max = rtSdk.rlim_cur = 100;
    if(setrlimit(RLIMIT_NOFILE, &rtSdk) == RESULT_FAIL)
    {
        WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NONE, DEBUG_FLAG_OPEN, "SdkServer set rlimit fail, now exit process!");
        exit(0);
    }

    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_NOTICE, g_enDebugFlag, "2. InitSdkServer!");
    LONG lResult = RESULT_SUCCESS;
    /* 2.初始化 */
    lResult = InitSdkServer();
    if(RESULT_FAIL == lResult)
    {
        WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NONE, DEBUG_FLAG_OPEN, "InitSdkServer fail, now exit process!");
        exit(0);
    }

    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_NOTICE, g_enDebugFlag, "3. Create epoll fd!");
    /*3.创建epoll句柄,把监听的socket加入到 epoll */
    g_iEpollFd = epoll_create(EPOLL_MAX_EVENT);
    if(InvalidFd == g_iEpollFd)
    {
        lResult = ReleaseSdkServer();
        WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NONE, DEBUG_FLAG_OPEN, "Create epoll fail, now exit process!");
        exit(0);
    }

    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_NOTICE, g_enDebugFlag, "4. BuildTcpSocket and SetNonBlock!");

    /* 4.建立TCP连接  */
    lResult = BuildTcpSocket(&g_stTcpSock);
    if(RESULT_FAIL == lResult)
    {
        lResult = ReleaseSdkServer();
        WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NONE, DEBUG_FLAG_OPEN, "BuildTcpSocket fail, now exit process!");
        exit(0);
    }

    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_NOTICE, g_enDebugFlag, "5. Epoll ctl add tcp listen read event and set Edge Triggered mode!");
    evEpoll.events  = EPOLLIN;  /* 监听读事件并设置LT模式 */
    evEpoll.data.fd = g_stTcpSock.lTcpFd;  /* 将全局的TCP listenFd 添加的epoll的事件 */

    if(epoll_ctl(g_iEpollFd, EPOLL_CTL_ADD, g_stTcpSock.lTcpFd, &evEpoll) < 0)
    {
        lResult = ReleaseSdkServer();
        WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NONE, DEBUG_FLAG_OPEN, "EPOLL_CTL_ADD tcp fd fail, now exit process!");
        exit(0);
    }

    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_NOTICE, g_enDebugFlag, "6. BuildUnixSocket and SetNonBlock!");
    /* 5.建立域套接字连接*/
    g_lUnixFd = BuildUnixSocket(PATH_SDK);
    if(RESULT_FAIL == g_lUnixFd)
    {
        lResult = ReleaseSdkServer();
        WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NONE, DEBUG_FLAG_OPEN, "BuildUnixSocket fail, now exit process!");
        exit(0);
    }
    if(RESULT_FAIL == SetSockBlock(g_lUnixFd, FALSE))
    {
        lResult = ReleaseSdkServer();
        close(g_lUnixFd);
        WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NONE, DEBUG_FLAG_OPEN, "Set g_lUnixFd NonBlock fail, now exit process!");
        exit(0);
    }

    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_NOTICE, g_enDebugFlag, "7. Epoll ctl add unix domain read event and set Edge Triggered mode!");
    evEpoll.events  = EPOLLIN;    /* 监听读事件并设置LT模式 */
    evEpoll.data.fd = g_lUnixFd;  /* 将全局的TCP listenFd 添加的epoll的事件 */

    if(epoll_ctl(g_iEpollFd, EPOLL_CTL_ADD, g_lUnixFd, &evEpoll) < 0)
    {
        lResult = ReleaseSdkServer();
        WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NONE, DEBUG_FLAG_OPEN, "EPOLL_CTL_ADD unixdomain fd fail, now exit process!");
        exit(0);
    }
    /* 设置当前监听的FD数目为2:TCPlistenFd UnixDomainFd */
    INT iCurFdNum = 2;
    INT iActiveFdNum = 0;  /* epoll_wait返回的需要处理的事件数目 */
    INT iTimeOut     = 2 * CONN_SECOND_IN_MS;  /* epoll_wait的超时时间,默认2秒 */
    INT iCurFd = -1;
    INT iNewClientFd = -1;

    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_NOTICE, g_enDebugFlag, "8. Enter main loop!");


    /* 进入主循环 */
    while(1)
    {
        /* 等待有事件发生,非阻塞模式 */
        iActiveFdNum = epoll_wait(g_iEpollFd, evEpollEvents, iCurFdNum, iTimeOut);
        if(0 > iActiveFdNum)
        {
            WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, "epoll_wait[%d] error!", g_iEpollFd);
            continue;
        }

        for(iCurFd = 0; iCurFd < iActiveFdNum; ++iCurFd)
        {
            if(evEpollEvents[iCurFd].data.fd == g_stTcpSock.lTcpFd)  /* 新客户连接事件 */
            {
                iNewClientFd = HandleTcpAccept(evEpollEvents[iCurFd].data.fd);
                if(RESULT_FAIL == iNewClientFd)
                {
                    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_WARNING, g_enDebugFlag,
                        "HandleTcpAccept fail, TcpFd = %d, new client fd = %d!", evEpollEvents[iCurFd].data.fd, iNewClientFd);
                    continue;
                }

                evEpoll.events  = EPOLLIN;  /* 监听读事件并设置为LT模式 */
                evEpoll.data.fd = iNewClientFd;  /* 将新连接的ClientFd 添加的epoll的事件 */
                if(epoll_ctl(g_iEpollFd, EPOLL_CTL_ADD, iNewClientFd, &evEpoll) < 0)
                {
                    if(RESULT_SUCCESS != DeleteClientNode(g_pstClientInfo, iNewClientFd))
                    {
                        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag,
                            "DeleteClientNode error, ClientFd = %d!", iNewClientFd);
                    }
                    CloseTcp(iNewClientFd, g_iEpollFd);

                    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_WARNING, g_enDebugFlag,
                        "EPOLL_CTL_ADD fail, Deleted Client Node, ClientFd = %d!", iNewClientFd);
                    continue;
                }

                /* 当前监听的FD数目++ */
                iCurFdNum++;

                /* 操作日志,新客户上线   */
            }
            else if(evEpollEvents[iCurFd].data.fd == g_lUnixFd)  /* 域套接字可读事件 */
            {
                lResult = HandleUnixRead(evEpollEvents[iCurFd].data.fd);
                if(RESULT_SUCCESS != lResult)
                {
                    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag,
                        "HandleUnixRead fail, fd = %d!", evEpollEvents[iCurFd].data.fd);
                    continue;
                }
            }
            else  /* 客户连接可读事件 */
            {
                lResult = HandleTcpRead(evEpollEvents[iCurFd].data.fd);
                if(RESULT_FAIL == lResult)
                {
                    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_WARNING, g_enDebugFlag,
                        "HandleTcpRead fail, fd = %d!", evEpollEvents[iCurFd].data.fd);
                    lResult = GetSockState(evEpollEvents[iCurFd].data.fd);
                    if(TCP_ESTABLISHED != lResult)
                    {
                        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_WARNING, g_enDebugFlag,
                            "GetSockState error, ClientFd = %d, Result = %d!", evEpollEvents[iCurFd].data.fd, lResult);

                        CLIENT_INFO_NODE_S * pstCurrentClientNode = NULL;
                        pstCurrentClientNode = GetClientInfoByClientFd(g_pstClientInfo, evEpollEvents[iCurFd].data.fd);
                        if(NULL == pstCurrentClientNode)
                        {
                            WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag,
                                "GetClientInfoByClientFd error, ClientFd = %d!", evEpollEvents[iCurFd].data.fd);
                        }
                        else
                        {
                            if(TRUE == pstCurrentClientNode->bUpgrade)
                            {
                                MSG_DATA_S stMsgData = {0};
                                stMsgData.enCmdType = CMD_UPGRADE_STOP;
                                stMsgData.enMsgType = MSG_SET;
                                strncpy(stMsgData.szClientUserName, SDK, CLIENT_NAME_LEN_MAX);
                                stMsgData.ulClientPort = (ULONG)pstCurrentClientNode->stClientAddr.sin_port;
                                strncpy(stMsgData.szClientIp, inet_ntoa(pstCurrentClientNode->stClientAddr.sin_addr),IP_ADDR_LEN_MAX);
                                strncpy(stMsgData.szDst, PATH_CONTROL, ADDR_LEN);
                                strncpy(stMsgData.szSrc, PATH_SDK, ADDR_LEN);
                                lResult = SendMsgToUnixSocket(&stMsgData,PATH_CONTROL);
                                if(RESULT_SUCCESS != lResult)
                                {
                                    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag,"SendMsgToControl fail.");
                                }
                                else
                                {
                                    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_INFO, g_enDebugFlag,"Send Msg To control stop uprade success!");
                                }

                                //删除写入的升级文件
                                lResult = DeleteUpgradeFile();
                                if(RESULT_SUCCESS != lResult)
                                {
                                    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag,"DeleteUpgradeFile fail.");
                                }
                            }
                        }

                        if(RESULT_SUCCESS != DeleteClientNode(g_pstClientInfo, evEpollEvents[iCurFd].data.fd))
                        {
                            WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag,
                                "DeleteClientNode error, ClientFd = %d!", evEpollEvents[iCurFd].data.fd);
                        }

                        CloseTcp(evEpollEvents[iCurFd].data.fd, g_iEpollFd);

                        /*如果没有客户端在连接,取消告警订阅*/
                        if(0 == g_pstClientInfo->lClientNum)
                        {
                            MSG_DATA_S stMsgData ;
                            memset(&stMsgData, 0x00, sizeof(MSG_DATA_S));
                            stMsgData.enMsgType = MSG_NOTIFY;
                            stMsgData.enCmdType = CMD_ALARM_SUBSCRIPTION;
                            stMsgData.enResultType = RESULT_SUCCESS;
                            strncpy(stMsgData.szDst, PATH_CONTROL, ADDR_LEN);
                            strncpy(stMsgData.szSrc, PATH_SDK, ADDR_LEN);
                            strncpy(stMsgData.szClientIp, "127.0.0.1", IP_ADDR_LEN_MAX);
                            strncpy(stMsgData.szClientUserName, SDK, CLIENT_NAME_LEN_MAX);
                            stMsgData.unCmdBody.stAlarmSubscription.enAlarmType = ALARM_TYPE_ALL;
                            stMsgData.unCmdBody.stAlarmSubscription.enSubcription = ENABLE_FALSE;

                            if(RESULT_FAIL == SendMsgToUnixSocket(&stMsgData, PATH_CONTROL))
                            {
                                WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, "Send cancel alarm subscription to control fail!");
                            }
                            else
                            {
                                WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_INFO, g_enDebugFlag, "Send cancel alarm subscription to control success!");
                            }
                        }

                        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag,
                            "Client abnormal exit, Close client Socket and free client node, fd = %d!", evEpollEvents[iCurFd].data.fd);

                        /* 操作日志,客户异常掉线   */
                    }
                }
            }
        }
    }

    WRITE_LOG(LOG_TYPE_CRITICAL, LOG_LEVEL_NONE, DEBUG_FLAG_OPEN, "0. Main loop terminate, now exit process!");
    CLOSE_LOG();
    lResult = ReleaseSdkServer();
    exit(0);
}

posted on 2012-11-01 11:50  xuejianhui  阅读(233)  评论(0编辑  收藏  举报