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