最近在研究sip相关的一些东西,单个idoubs在iphone上可以正常运行,但是同时运行两个的话,会有一个注册不到服务器,抓包跟了好久都不知道是什么问题,例如现在有两个idoubs在iphone上,,暂且命名为idoubs1和idoubs2吧.它们两个是分别连接到不同的服务,接收的端口也是不一样的.
如果我先运行idoubs1,正常连接之后,再开启idoubs2,这时idoubs2却连接不上服务器了.实际上idoubs2有发了注册消息给服务器.服务器也返回了消息给idoubs2.但是sip层中用于接收sip消息的函数
static int tsip_transport_layer_stream_cb(const tnet_transport_event_t* e)却没有响应,接着,我只能把断点设到udp层的recvfrom()函数里面,调试了很多次发现设在recvfrom()函数前面的断点没有停,弄了好久也不知道什么原因,以为不是用recvfrom()来接收udp消息的,但那又不可能呀..后来把工程cleanup一遍,recvfrom()前的断点终于停下来了,把收到的消息打印出来,发现程序是收到了消息的.关键是在把消息传到sip层的时候出了问题.
接着发了在static int tsip_transport_layer_stream_cb(const tnet_transport_event_t* e)这个函数所回调的地方,有个宏定义的信号量,这个宏定义有点奇怪.
#define TSK_RUNNABLE_RUN_BEGIN(self) \ TSK_RUNNABLE(self)->running = tsk_true; \ for(;;) { \ tsk_semaphore_decrement(TSK_RUNNABLE(self)->semaphore); \ if(!TSK_RUNNABLE(self)->running && \ (!TSK_RUNNABLE(self)->important || (TSK_RUNNABLE(self)->important && TSK_LIST_IS_EMPTY(TSK_RUNNABLE(self)->objects)))) \ break; #define TSK_RUNNABLE_RUN_END(self) \ } \ TSK_RUNNABLE(self)->running = tsk_false;两个宏, ,,其实就是把一段代码拆分到两个宏定义里面,然后回调函数就是在两个宏之间:
TSK_RUNNABLE_RUN_BEGIN(transport); if((curr = TSK_RUNNABLE_POP_FIRST_SAFE(TSK_RUNNABLE(transport)))){ const tnet_transport_event_t *e = (const tnet_transport_event_t*)curr->data; if(transport->callback){ transport->callback(e); } tsk_object_unref(curr); } TSK_RUNNABLE_RUN_END(transport);注意到第一个宏里面的
tsk_semaphore_decrement()原来doubango里面udp层和sip层之间是用sem_t信号量来通信的.因为信号量是可以实现进程间通信的,突然间明白为什么idoubs2的收不到sip消息了,如果信号量的标识符是一样的话,那idoubs2的消息有可能发到idoubs1那里去了,,
接着再去查信号量的初始化
找到了这个函数
tsk_semaphore_handle_t* tsk_semaphore_create_2(int initial_val)
tsk_semaphore_handle_t* tsk_semaphore_create_2(int initial_val) { SEMAPHORE_T handle = tsk_null; #if TSK_UNDER_WINDOWS handle = CreateSemaphore(NULL, initial_val, 0x7FFFFFFF, NULL); #else handle = tsk_calloc(1, sizeof(SEMAPHORE_S)); #if TSK_USE_NAMED_SEM named_sem_t * nsem = (named_sem_t*)handle; tsk_sprintf(&(nsem->name), "/sem-%d", sem_count++); if((nsem->sem = sem_open(nsem->name, O_CREAT /*| O_EXCL*/, S_IRUSR | S_IWUSR, initial_val)) == SEM_FAILED) { TSK_FREE(nsem->name); #else if(sem_init((SEMAPHORE_T)handle, 0, initial_val)) { #endif TSK_FREE(handle); TSK_DEBUG_ERROR("Failed to initialize the new semaphore (errno=%d).", errno); } #endif if(!handle){ TSK_DEBUG_ERROR("Failed to create new semaphore"); } return handle; }查了一下资料,,定位到
tsk_sprintf(&(nsem->name), "/sem-%d", sem_count++);只要把"/sem-%d" 改成不一样就行了.."/1sem-%d"..
问题就终于解决啦..