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);
}