doubango(3)--协议栈的启动过程
协议栈启动的上层接口
对于Doubango中得sip协议栈,是通过SipStack类粘合上层代码与底层代码的,该类定义在SipStack.h中,实现在SipStack.cxx中。当构造好一个SipStack实例之后,对于底层而言,实际上是创建了一个tsip_stack_t 的实例,这个实例在SipStack类中通过tsip_stack_handle_t *handle字段指向。此时,handle对于上层而言是不透明的,从tsip_stack_handle_t的定义也可以看出:
typedefvoid tsip_stack_handle_t
因此,handle实际上是一个void指针。指向具体的tsip_stack_t实例。实际上,stack的底层实例已经创建好,并且已经设置好了很多字段信息。但是stack仍旧是没有启动的,若要启动协议栈,对于上层代码而言,可以通过SipStack->start()达到此目的。
SipStack->start(),正是提供给上层启动底层协议栈的粘合接口。而该接口仅仅是对底层协议栈启动的真正函数tsip_stack_start(tsip_stack_t *stack)函数的一个封装而已。
底层协议栈的启动--tsip_stack_start(…)
tsip_stack_start(tsip_stack_t *stack)函数主要完成三件事情:
1. 对协议栈运行模式的处理
判断工作模式为服务器模式或者是客户端模式,在默认情况下,Doubango是作为一个客户端软电话的底层运作机制配置的,因此在这种情况下,我们得到的是客户端运行模式。
另外,还要判断网络层协议族和传输层(tcp,udp)类型,默认情况下为IPV4以及UDP。选择一个最合适的本地ip地址(根据目前的网口选择)网口的IP地址最终由getaddrinfo(…)获得。
2. 启动协议栈的sipevent 事件处理线程run(…)
在stack的结构中,有一个TSK_DECLARE_RUNNABLE的宏声明,这个宏实际上在stack的顶端嵌入了一个tsk_runnable_t__runnable__的结构实例,因此,stack可以被安全的强制转化为一个tsk_runnable_t的类型实例,而这就是TSK_RUNNABLE宏的作用。
TSK_RUNNABLE(stack)->objects是一个队列头,传入其中的元素是通用的tsk_list_item_t,而tsk_list_item_t的作用就是将一个需要记录的实例(任何结构的实例)挂接在tsk_list_item_t的void *data 字段。
因此,TSK_RUNNABLE(stack)->objects实际上是一个队列,该队列中挂载的结构实例便是tsip_event_t结构的实例。
Stack的run(…)线程在stack的生存周期内一直在运行,它的作用是从TSK_RUNNABLE(stack)->objects中取出一个tsip_event_t实例,然后通过注册到stack的回调函数,将该sip事件传递到高层的用户代码中。实际上,这里的传递需要穿越粘合层,因为stack中回调函数即stack->callback(…),便是由SipStack类注册的stack_callback(…)函数,该函数的原型如下:
int stack_callback(tsip_event_t*sipevent);
3. 启动协议栈的传输层——tsip_transport_layer
首先,生成一个默认的tsip_transport_t实例,链接如stack的tsip_transport_layer的transports队列。
其次,启动tsip_transport_layer,这里便完成了套接字的生成,端口绑定,若是tcp协议还要完成connect的相关事宜。
到了这里,粘合层的任务便已经完成了,底层的套接口已经启动,可以接受来自对端的sip消息和处理该sip消息了。
doubango(3)--协议栈的启动过程的更多相关文章
- 11.Linux启动过程详解
目录: 本文转载自:http://blog.csdn.net/miss_acha/article/details/50004717 经过对Linux系统有了一定了解和熟悉后,想对其更深层次的东西做进一 ...
- CentOS6与CentOS7的启动过程
Linux启动流程CentOS6的启动流程Systemd概述Systemd初始化进程Systemd目标名称systemd服务管理 linux系统的组成:内核+跟文件系统 内核可实现以下功能:进程管理. ...
- zookeeper源码分析之一服务端启动过程
zookeeper简介 zookeeper是为分布式应用提供分布式协作服务的开源软件.它提供了一组简单的原子操作,分布式应用可以基于这些原子操作来实现更高层次的同步服务,配置维护,组管理和命名.zoo ...
- [原] KVM 虚拟化原理探究(2)— QEMU启动过程
KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...
- Openfire的启动过程与session管理
说明 本文源码基于Openfire4.0.2. Openfire的启动 Openfire的启动过程非常的简单,通过一个入口初始化lib目录下的openfire.jar包,并启动一个 ...
- 探索 Linux 系统的启动过程
引言 之所以想到写这些东西,那是因为我确实想让大家也和我一样,把 Linux 桌面系统打造成真真正正日常使用的工具,而不是安装之后试用几把再删掉.我是真的在日常生活和工作中都使用 Linux,比如在 ...
- Linux内核启动过程概述
版权声明:本文原创,转载需声明作者ID和原文链接地址. Hi!大家好,我是CrazyCatJack.今天给大家带来的是Linux内核启动过程概述.希望能够帮助大家更好的理解Linux内核的启动,并且创 ...
- SpringMVC启动过程详解(li)
通过对SpringMVC启动过程的深入研究,期望掌握Java Web容器启动过程:掌握SpringMVC启动过程:了解SpringMVC的配置文件如何配置,为什么要这样配置:掌握SpringMVC是如 ...
- Android源码——Activity组件的启动过程
根Activity启动过程 Launcher启动MainActivity的过程主要分为6个步骤: 一.Launcher向ActivityManagerService发送一个启动MainActivity ...
随机推荐
- PAT 天梯赛 L2-005 集合相似度
set的应用 题目链接 题解 有点像集合的交并操作,直接利用set进行处理,因为set有去重的功能,而且set是利用红黑树实现的,查找速度快O(logN). 代码如下: #include<cst ...
- Android Service生命周期 Service里面的onStartCommand()方法详解
在Demo上,Start一个Service之后,执行顺序:onCreate - > onStartCommand 然后关闭应用,会重新执行上面两步. 但是把代码拷贝到游戏工程发现,关闭游戏后,只 ...
- windows矢量字体点阵数据的提取(转)
源:windows矢量字体点阵数据的提取 问题参考:windows api 获取字库点阵的问题 1.提取原理 在windows系统当中提取矢量字体的字模有很多方法,下面介绍一种利用GetGlyphOu ...
- find命令--xargs--exec
find命令 1.1.find命令选项-name 按照文件名查找-perm 按照文件权限来查找-prune 可以使用find命令排除当前文件夹,不查找-user 可以按照文件属主来查找-group 可 ...
- 用于辅助在 bootstrap-dialog 中的表现:app-jquery-dialog.js
// 用于通某个元素共享配置数据 $.extend($.fn, { formOption : function(showOpt) { var opt = $.data(this[0], "f ...
- (中等) HDU 3335 , DLX+重复覆盖。
Description As we know,the fzu AekdyCoin is famous of math,especially in the field of number theory. ...
- phpcms v9 后台首页 去掉团队信息等版权
phpcms\languages\zh-cn\admin.lang.php $LANG['main_product_team'] = 'PHPCMS开发团队'; phpcms\modules\admi ...
- html5 js控制音乐播放
<!DOCTYPE HTML><html><head><meta charset="UTF-8"><script lang ...
- Postman 测试web接口(推荐)
- STM32单片机在Keil5下仿真的问题解决及GPIO口初始化、使用
STM32单片机在Keil5下仿真的问题解决及GPIO口初始化.使用 最近看了视频,里面有仿真,可以清楚看到GPIO口的数据变化,也想尝试下,DUG时却出现*** error 65: access v ...