GB28181學習之路——eXosip TCP模式

eXosip 的TCP模式與UDP模式大致相同,基本代碼如下:

bool CSipContact::initialize()
{
    int i;
    TRACE_INITIALIZE (6, NULL);
    m_ctx = eXosip_malloc();
    if (m_ctx==NULL)
    {
        FLOG("eXosip_malloc failed\n");
        return -1;
    }
    i=eXosip_init(m_ctx);
    if (i!=0)
    {
        FLOG("eXosip_init failed\n");
        return -1;
    }
    i = eXosip_listen_addr(m_ctx, IPPROTO_TCP, NULL, 5060, AF_INET, 0);
    if (i!=0)
    {
        eXosip_quit(m_ctx);
        FLOG ("could not initialize transport layer\n");
        return -1;
    }
    return 0;
}

void* CSipContact::enterSipEventLoop(void*)
{
    int counter = 0;
    /* use events to print some info */
    eXosip_event_t *je;
    osip_message_t *ack = NULL;
    osip_message_t *answer = NULL; 

    for (;;)
    {
        je = eXosip_event_wait (m_ctx, 0, 50);
        eXosip_lock (m_ctx);
        eXosip_default_action (m_ctx, je);
        eXosip_unlock (m_ctx);
        if (je == NULL)
            continue;
	    // printf("type:%d\n%s\n", je->type, strReq);
        switch(je->type)
        {
        case EXOSIP_MESSAGE_NEW://新的消息到來   
            FLOG ("EXOSIP_MESSAGE_NEW!\n");  
            break;  

        case EXOSIP_REGISTRATION_SUCCESS:// 註冊成功
        {
            FLOG("EXOSIP_REGISTRATION_SUCCESS:%d\n", je->rid); 
            break;
        }
        case EXOSIP_REGISTRATION_FAILURE:// 註冊失敗
            FLOG("EXOSIP_REGISTRATION_FAILURE\n");
            if (je->response != NULL &&
                (je->response->status_code == 401 || je->response->status_code == 407))
            {
            }
            else
            {
                FLOG("register really failed\n"); 
            }
            break;

        case EXOSIP_CALL_INVITE:
            FLOG ("a new invite reveived!\n");
            break;
        case EXOSIP_CALL_ANSWERED:
        case EXOSIP_MESSAGE_ANSWERED:
        {
            FLOG ("EXOSIP_CALL_ANSWERED || EXOSIP_MESSAGE_ANSWERED\n");
            osip_message_t* ack;
            eXosip_call_build_ack(m_ctx,je->did, &ack);
            eXosip_call_send_ack(m_ctx,je->did, ack);
            break;
        }
        default:
            FLOG ("other response!\n");
            break;
        }
        eXosip_event_free (je);
    }
}

以上可以看出,TCP相對於UDP只是將IPPROTO_UDP改成了IPPROTO_TCP,這樣還是非常方便的,給作者點個贊。

但是可能會遇到一些問題,比如理論上來說TCP建立起來後,後續的消息都會在這個TCP連接上進行收發,當然這是在知道對端的IP端口的情況下。

由於TCP連接時,發起者比如設備,在建立建立連接時所使用的端口是隨機的,這就會造成一些麻煩,使用其他端口回傳的時候,往往會又建立了一個新的TCP連接,雖然能通信成功,但是並不是一個好的做法。

以下是獲取源端口的方法:

if (MSG_IS_REGISTER(je->request))
{
    FLOG ("MSG_IS_REGISTER!\n");  
    eXosip_lock (m_ctx);
    eXosip_message_build_answer (m_ctx, je->tid, 200, &asw_register);
    eXosip_message_send_answer (m_ctx, je->tid, 200, asw_register);
    eXosip_unlock (m_ctx);
    char addr[20];
    int port;
    osip_via_t* via;
    osip_message_get_via(asw_register, 0, &via);
    strcpy(addr, via->host);
    osip_generic_param_t* rport;
    osip_via_param_get_byname(via, "rport", &rport);
    port = atoi(rport->gvalue);
}

 

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