int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        printf("Usage : %s <server_port>\n", argv[0]);
        return 0;
    }

    EventLoop loop;
    InetAddress serverAddr("127.0.0.1", atoi(argv[1]));

    const static int flag = 2;
    if (flag == 1)
    {
        TcpClient client(&loop, serverAddr);
        client.enableRetry();
        client.setConnectionCallback(test_client::clientConnectionCallback);
        client.setMessageCallback(test_client::clientMessageCallback);
        client.connect();
        loop.addTimer(test_client::sendDataByClient, 1, true);   //启动一个每1s运行一次的定时器
        loop.loop();
    }
    else if (flag == 2)
    {
        test_client_stdin::TestTcpClient client(&loop, serverAddr);
        client.connect();
        loop.loop();
    }
}
eIOnDemandStatus VOD_SessionControl::AddMessageToSendList(SendMsgInfo *msgInfo)
{
    //create a timer call back
    uint32_t tMsg = 0;

    pthread_mutex_lock(&mVodSessionListMutex);

    EventLoop* evtLoop = ptrOnDemand->GetEventLoop();
    OnDemandSystemClient::getInstance()->GetmessageTimer(&tMsg);

    //if retry count is more then one then add message to send list
    if ((evtLoop != NULL) && (msgInfo->msgRetryCount > 0))
    {
        EventTimer* evtTimer = evtLoop->addTimer(EVENTTIMER_TIMEOUT,
                               tMsg,
                               0,
                               VOD_SessionControl::ProcessTimeoutCallBack, (void *)msgInfo);


        LOG(DLOGL_REALLY_NOISY, "evtLoop->addTimer: evtTimer: %p  transId: %d time: %d secs", evtTimer, msgInfo->transId,  tMsg);

        // add to queue
        msgInfo->evtTimer = evtTimer;
        msgInfo->objPtr = this;
        msgInfo->ptrOnDemand = ptrOnDemand;
        msgInfo->sessionId = mVodSessionId;
        LOG(DLOGL_REALLY_NOISY, " msginfo:%p  evtTimer: %p ", msgInfo,  msgInfo->evtTimer);
        sendMsgInfoList.push_back(msgInfo);

        LOG(DLOGL_REALLY_NOISY, "sendMsgInfoList.size(): %d", sendMsgInfoList.size());
    }
    else
    {
        delete msgInfo;
    }


    pthread_mutex_unlock(&mVodSessionListMutex);

    return ON_DEMAND_OK;
}
void VOD_SessionControl::ProcessTimeoutCallBack(int32_t fd, short event, void *arg)
{
    (void) fd;
    (void) event;

    pthread_mutex_lock(&mVodSessionListMutex);

    EventTimer* pEvt = (EventTimer*) arg;
    if (NULL != pEvt)
    {

        SendMsgInfo *msgInfo = (SendMsgInfo *) pEvt->getUserData();
        if (NULL != msgInfo)
        {
            unsigned int sessId = msgInfo->sessionId;

            LOG(DLOGL_REALLY_NOISY, " MessageTimeoutCallBack : %d ", msgInfo->transId);

            // TODO: this is dangerous because VOD_SessionControl object may be gone
            //       Is there way for onDemand controller to handle this?

            ActiveVodSessionMap::iterator it;
            bool found = false;

            for (it = mActiveVodSessionMap.begin(); it != mActiveVodSessionMap.end(); ++it)
            {
                if (it->first == sessId)
                {
                    found = true;
                    break;
                }
            }

            LOG(DLOGL_MINOR_EVENT, "sessId: %d  found: %d", sessId, found);

            if (found)
            {
                //if message exist in queue then resend
                list<SendMsgInfo *>::iterator itr;

                VOD_SessionControl *objPtr = msgInfo->objPtr;
                for (itr = objPtr->sendMsgInfoList.begin(); itr != objPtr->sendMsgInfoList.end(); ++itr)
                {
                    if (msgInfo->transId == (*itr)->transId)
                    {
                        LOG(DLOGL_REALLY_NOISY, "SendPendingMessage: evtTimer: %p  transId: %d", pEvt, msgInfo->transId);

                        if (((*itr)->msgRetryCount <= 1))
                        {
                            objPtr->sendMsgInfoList.remove(*itr);
                            delete *itr;
                            *itr = NULL;

                            if (msgInfo->ptrOnDemand)
                            {
                                LOG(DLOGL_ERROR, " NOT RECEIVED SERVER RESPONSE  - sending error to service layer !!");
                                msgInfo->ptrOnDemand->queueEvent(kOnDemandSessionErrorEvent);
                            }
                        }
                        else
                        {
                            //resend the message
                            objPtr->SendPendingMessage(*itr);
                            (*itr)->msgRetryCount--;
                            LOG(DLOGL_NORMAL, "Add message timer event for retry msgRetryCount::%d", (*itr)->msgRetryCount);
                            EventLoop* evtLoop = (*itr)->ptrOnDemand->GetEventLoop();

                            if (evtLoop != NULL)
                            {
                                uint32_t tMsg = 0;
                                OnDemandSystemClient::getInstance()->GetmessageTimer(&tMsg);
                                EventTimer* evtTimer = evtLoop->addTimer(EVENTTIMER_TIMEOUT,
                                                       tMsg,
                                                       0,
                                                       VOD_SessionControl::ProcessTimeoutCallBack, (void *)(*itr));
                                (*itr)->evtTimer = evtTimer;
                            }
                        }
                        break;
                    }
                }
            }
            else
            {
                LOG(DLOGL_MINOR_EVENT, "Warning: no action - sessId: %d no longer active", sessId);
            }
        }
        delete pEvt;
        pEvt = NULL;
    }
    pthread_mutex_unlock(&mVodSessionListMutex);
}