PJSIP简介配置和PJLIB基础库的使用
2014-04-15 14:59
337 查看
PJSIP的实现是为了能在嵌入式设备上高效实现SIP/VOIP.
1.PJSIP库的主要特征:
1).极具移植性.(Extremelyportable)
当前可支持平台包括:
*Win32/x86(Win95/98/ME,NT/2000/XP/2003,mingw).
*arm,WinCEandWindowsMobile.
*Linux/x86,(usermodeandaskernelmodule(!)).
*Linux/alpha
*Solaris/ultra.
*MacOSX/powerpc
*RTEMS(x86andpowerpc).
*SymbianOS
2).非常小的足印.(Verysmallfootprint)
官方宣称编译后的库<150Kb,我在PC上编译后加上strip后大概173Kb,这对于嵌入
式设备,是个好消息
3).高性能.(Highperformance)
这点我们后面可以看看是否如作者宣称的
2.PJSIP的组成.
其实说是PJSIP不是特别贴切,这个库实际上是几个部分组成的.
1).PJSIP-OpenSourceSIPStack[开源的SIP协议栈]
2).PJMEDIA-OpenSourceMediaStack[开源的媒体栈]
3).PJNATH-OpenSourceNATTraversalHelperLibrary[开源的NAT-T****库]
4).PJLIB-UTIL-AuxiliaryLibrary[****工具库]
5).PJLIB-UltraPortableBaseFrameworkLibrary[基础框架库]
PJLIB-UTIL****工具库:加解密MD5和CRC32的算法
PJNATH开源的NAT库包含ICE打洞
PJSUA-LIB库:最顶层的SIP库支持VOIP
PJMEDIA库:最顶层的支持视频的库
3.PJLIB基础框架库提供的功能:
1).内存的处理、数据的存储
.数据结构的(hash表、link表、二叉树、等)
.caching和pool;缓冲池和内存池
2).OS抽象
.线程、互斥、临界区、锁对象、事件对象
.定时器
.pj_str_t字符串
3).操作系统级别的函数抽象
.socket的抽象(tcp/udp)
.文件的读写
4).使用前的初始化,使用后的清理
4.PJSIP的安装和配置:
1.安装和编辑pjsip库:
A.将pjproject-1.5.zip和DirectX-Lib.rar解压到当前目录的pjlib路径下;
B.查看pjlib\pjproject-1.5\pjlib\include\pj下面是否有config_site.h,如果没有建一个空文件
C.将DirectX的x86的lib库拷贝到C:\ProgramFiles\MicrosoftVisualStudio8\VC\PlatformSDK\Lib
D.在环境变量中设置DXSDK_DIR=direx中的include目录
E.首先编译pjlib\pjproject-1.5\pjproject-vs8.sln[win32]
F.然后打开工程开始编译
2.脱离pjsip环境的工程的配置
需要头文件的可以加入
$(SolutionDir)pjlib\pjproject-1.5\pjlib\include
$(SolutionDir)pjlib\pjproject-1.5\pjlib-util\include
$(SolutionDir)pjlib\pjproject-1.5\pjnath\include
$(SolutionDir)pjlib\pjproject-1.5\pjsip\include
$(SolutionDir)pjlib\pjproject-1.5\pjmedia\include
如果需要lib库文件的加入
$(SolutionDir)pjlib\pjproject-1.5\pjlib\lib
$(SolutionDir)pjlib\pjproject-1.5\pjlib-util\lib
$(SolutionDir)pjlib\pjproject-1.5\pjnath\lib
$(SolutionDir)pjlib\pjproject-1.5\pjsip\lib
$(SolutionDir)pjlib\pjproject-1.5\pjmedia\lib
$(SolutionDir)pjlib\pjproject-1.5\lib
我的程序所依赖PJLIB的库有:
pjlib-i386-Win32-vc8-Debug.lib
pjlib-util-i386-Win32-vc8-Debug.lib
pjnath-i386-Win32-vc8-Debug.lib
pjsip-core-i386-Win32-vc8-Debug.lib
pjsip-simple-i386-Win32-vc8-Debug.lib
pjsip-ua-i386-Win32-vc8-Debug.lib
pjsua-lib-i386-Win32-vc8-Debug.lib
pjmedia-audiodev-i386-Win32-vc8-Debug.lib
pjmedia-codec-i386-Win32-vc8-Debug.lib
pjmedia-i386-Win32-vc8-Debug.lib
libpjproject-i386-Win32-vc8-Debug.lib
1.使用前的初始化和使用后的清理
PJSIP库里面封装了很多线程内存池;而且很多对象都是基于内存池创建的,所以几乎所以的库都需要初始化或创建
下面是pjlib,pjlib-util,pjnath,pjsua-lib库的初始化和关闭
显示行号复制代码这是一段程序代码。
pj_status_tstatus;
2.缓冲池和内存池(caching,pool)
pjsip的内存池的使用规则:
每个内存池都是基于内存池工厂创建的;pjsip有一个默认的内存池工厂pj_caching_pool;
我喜欢把它叫做缓冲池;将来清理内存池的时候,可以关闭内存池也可直接关闭缓冲池;
pj_caching_poolcp;
pj_caching_pool_init(&cp,NULL,1024*1024);//缓冲池
pj_caching_pool_destroy(&cp);//释放工厂
pj_pool_tpool=pj_pool_create(&cp.factory,"name",1024,1024,NULL);//创建内存池
pj_pool_release(&pool);//释放内存池到工厂中,直接释放工厂可省略这一步
void*p=pj_pool_alloc(pool,size);//在内存中开辟一个空间
注:适当的初始化大小;内存池只能增加不能减小
由于pjlib很多内部对象都用内存池,所以在对象释放之前不能释放内存池。
使用缓冲池和内存池
//系统初始化的时候调用
3.线程的介绍,及其线程的封装和使用
1.外部函数或线程使用到pjsip的时候,必须注册线程
隐藏行号复制代码注册线程
pj_thread_descdesc;
2.线程的创建和使用
pj_thread_create(pool*,"",function,*arg,stack_size,flag,**pj_thread_t)//创建一个线程
pj_thread_destroy(thread);//注销一个线程
pj_thread_resume(thread);//线程继续
pj_thread_sleep(1500);//当前的线程暂停1500毫秒
pj_thread_join(thrad);//等待线程结束
pj_thread_proc函数原型是:intthread_func(void*
argv);
3.对pjlib的thread的线程的封装
1:classCSipThread
4.使用封装起来的thread线程对象
1:/*使用封装后的线程注意事项
4.互斥和锁,及其封装(mutex)
pj_mutex_create(this->m_pool,"",PJ_MUTEX_SIMPLE,&this->m_pool_mutex);//创建一个锁指针
pj_mutex_destroy(this->m_pool_mutex);//删除锁指针
pj_mutex_lock(m_mutex);//加锁
pj_mutex_unlock(m_mutex);//解锁
1:/*封装了mutex的使用方法
5.定时器(heap,callback,thread)
//创建定时器堆,设置定时器堆pool大小
pj_timer_heap_create(this->m_pool,MAX_TIMER_COUTN,&this->timer_heap);
pj_timer_heap_set_max_timed_out_per_poll(this->timer_heap,20);
//对定时器加锁是lcok类型
pj_timer_heap_set_lock(this->timer_heap,this->timer_heap_lock,true);
//启动定时器轮询的线程
this->run_(this->m_pool,&CInterFace::timer_thread_fun);
//设置一个定时器
pj_timer_heap_schedule(this->timer_heap,entry,delay);
//取消一个定时器
pj_timer_heap_cancel(this->timer_heap,entry);
//定时器的入口点定义
structpj_timer_entry
{
void*user_data;//定时器的用户数据;C++通常用类对象;C通常用struct
intid;//绝对的ID号;用来区分当user_data和cb都相同的情况
pj_timer_heap_callback*cb;//定时器中的回调函数
};
//定时器回调函数的原型
voidtimer_callback(pj_timer_heap_t*timer_heap,structpj_timer_entry*entry);
一个定时器的使用例子:
1.创建一个定时器、创建一个线程
2.创建一个定时器入口entry
3.创建一个定时器的回调函数,在回调函数中必须重新将entry加入堆中
1://创建定时器堆,设置定时器堆pool大小;加锁;
6.pj_str_t字符串
7.socket的封装和使用
转至:http://www.zhimax.com/article/tcp/pjlib.html
1.PJSIP库的主要特征:
1).极具移植性.(Extremelyportable)
当前可支持平台包括:
*Win32/x86(Win95/98/ME,NT/2000/XP/2003,mingw).
*arm,WinCEandWindowsMobile.
*Linux/x86,(usermodeandaskernelmodule(!)).
*Linux/alpha
*Solaris/ultra.
*MacOSX/powerpc
*RTEMS(x86andpowerpc).
*SymbianOS
2).非常小的足印.(Verysmallfootprint)
官方宣称编译后的库<150Kb,我在PC上编译后加上strip后大概173Kb,这对于嵌入
式设备,是个好消息
3).高性能.(Highperformance)
这点我们后面可以看看是否如作者宣称的
2.PJSIP的组成.
其实说是PJSIP不是特别贴切,这个库实际上是几个部分组成的.
1).PJSIP-OpenSourceSIPStack[开源的SIP协议栈]
2).PJMEDIA-OpenSourceMediaStack[开源的媒体栈]
3).PJNATH-OpenSourceNATTraversalHelperLibrary[开源的NAT-T****库]
4).PJLIB-UTIL-AuxiliaryLibrary[****工具库]
5).PJLIB-UltraPortableBaseFrameworkLibrary[基础框架库]
PJLIB-UTIL****工具库:加解密MD5和CRC32的算法
PJNATH开源的NAT库包含ICE打洞
PJSUA-LIB库:最顶层的SIP库支持VOIP
PJMEDIA库:最顶层的支持视频的库
3.PJLIB基础框架库提供的功能:
1).内存的处理、数据的存储
.数据结构的(hash表、link表、二叉树、等)
.caching和pool;缓冲池和内存池
2).OS抽象
.线程、互斥、临界区、锁对象、事件对象
.定时器
.pj_str_t字符串
3).操作系统级别的函数抽象
.socket的抽象(tcp/udp)
.文件的读写
4).使用前的初始化,使用后的清理
4.PJSIP的安装和配置:
1.安装和编辑pjsip库:
A.将pjproject-1.5.zip和DirectX-Lib.rar解压到当前目录的pjlib路径下;
B.查看pjlib\pjproject-1.5\pjlib\include\pj下面是否有config_site.h,如果没有建一个空文件
C.将DirectX的x86的lib库拷贝到C:\ProgramFiles\MicrosoftVisualStudio8\VC\PlatformSDK\Lib
D.在环境变量中设置DXSDK_DIR=direx中的include目录
E.首先编译pjlib\pjproject-1.5\pjproject-vs8.sln[win32]
F.然后打开工程开始编译
2.脱离pjsip环境的工程的配置
需要头文件的可以加入
$(SolutionDir)pjlib\pjproject-1.5\pjlib\include
$(SolutionDir)pjlib\pjproject-1.5\pjlib-util\include
$(SolutionDir)pjlib\pjproject-1.5\pjnath\include
$(SolutionDir)pjlib\pjproject-1.5\pjsip\include
$(SolutionDir)pjlib\pjproject-1.5\pjmedia\include
如果需要lib库文件的加入
$(SolutionDir)pjlib\pjproject-1.5\pjlib\lib
$(SolutionDir)pjlib\pjproject-1.5\pjlib-util\lib
$(SolutionDir)pjlib\pjproject-1.5\pjnath\lib
$(SolutionDir)pjlib\pjproject-1.5\pjsip\lib
$(SolutionDir)pjlib\pjproject-1.5\pjmedia\lib
$(SolutionDir)pjlib\pjproject-1.5\lib
我的程序所依赖PJLIB的库有:
pjlib-i386-Win32-vc8-Debug.lib
pjlib-util-i386-Win32-vc8-Debug.lib
pjnath-i386-Win32-vc8-Debug.lib
pjsip-core-i386-Win32-vc8-Debug.lib
pjsip-simple-i386-Win32-vc8-Debug.lib
pjsip-ua-i386-Win32-vc8-Debug.lib
pjsua-lib-i386-Win32-vc8-Debug.lib
pjmedia-audiodev-i386-Win32-vc8-Debug.lib
pjmedia-codec-i386-Win32-vc8-Debug.lib
pjmedia-i386-Win32-vc8-Debug.lib
libpjproject-i386-Win32-vc8-Debug.lib
1.使用前的初始化和使用后的清理
PJSIP库里面封装了很多线程内存池;而且很多对象都是基于内存池创建的,所以几乎所以的库都需要初始化或创建
下面是pjlib,pjlib-util,pjnath,pjsua-lib库的初始化和关闭
显示行号复制代码这是一段程序代码。
pj_status_tstatus;
status=pj_init();//初始化pjlib库返回PJ_SUCCESS表示成功
status=pjlib_util_init();//初始化pjlib-util库
status=pjnath_init();//初始化pjnath库
status=pjsua_create();//初始化pjsua-lib库;(里面初始化了pjlib,pjlib-util,pjnath)
pj_shutdown();//pjlib停止
pjsua_destroy();//pjsua-lib库的清理
2.缓冲池和内存池(caching,pool)
pjsip的内存池的使用规则:
每个内存池都是基于内存池工厂创建的;pjsip有一个默认的内存池工厂pj_caching_pool;
我喜欢把它叫做缓冲池;将来清理内存池的时候,可以关闭内存池也可直接关闭缓冲池;
pj_caching_poolcp;
pj_caching_pool_init(&cp,NULL,1024*1024);//缓冲池
pj_caching_pool_destroy(&cp);//释放工厂
pj_pool_tpool=pj_pool_create(&cp.factory,"name",1024,1024,NULL);//创建内存池
pj_pool_release(&pool);//释放内存池到工厂中,直接释放工厂可省略这一步
void*p=pj_pool_alloc(pool,size);//在内存中开辟一个空间
注:适当的初始化大小;内存池只能增加不能减小
由于pjlib很多内部对象都用内存池,所以在对象释放之前不能释放内存池。
使用缓冲池和内存池
//系统初始化的时候调用
voidcreate()
{
//初始化pjlib库返回PJ_SUCCESS表示成功
pj_status_tstatus=pj_init();
pj_caching_pool_init(&this->m_caching,NULL,0);
this->m_pool=pj_pool_create(&this->m_caching.factory,"",256,256,NULL);
//初始化mutex
pj_mutex_create(this->m_pool,"",PJ_MUTEX_SIMPLE,&this->m_pool_mutex);
//创建一个lock给定时器用
pj_lock_create_simple_mutex(this->m_pool,"timer_lock",&this->timer_heap_lock);
//在内存池上开辟一块空间
char*pmem=(char*)pj_pool_alloc(this->m_pool,1024);
//创建一个定时器堆
pj_timer_heap_create(this->m_pool,MAX_TIMER_COUTN,&this->timer_heap);
//给定时器加锁;将来自动删除该锁,无需手工删除
pj_timer_heap_set_lock(this->timer_heap,this->timer_heap_lock,true);
}
//系统退出的时候调用
voiddestroy()
{
//删除mutex
pj_mutex_destroy(this->m_pool_mutex);
//删除定时器的堆
pj_timer_heap_destroy(this->timer_heap);
//清理内存池,这一步也可以删略;让caching_pool来清理
pj_pool_destroy_int(this->m_pool);
//清理缓冲池;所有在缓冲池建立的内存池都会被清理掉
pj_caching_pool_destroy(&this->m_caching);
//pjlib停止
pj_shutdown();
}
3.线程的介绍,及其线程的封装和使用
1.外部函数或线程使用到pjsip的时候,必须注册线程
隐藏行号复制代码注册线程
pj_thread_descdesc;
pj_bzero(desc,sizeof(desc));
pj_thread_t*thread_;
if(pj_thread_register("",desc,&thread_)!=PJ_SUCCESS)
return0;/*失败*/
2.线程的创建和使用
pj_thread_create(pool*,"",function,*arg,stack_size,flag,**pj_thread_t)//创建一个线程
pj_thread_destroy(thread);//注销一个线程
pj_thread_resume(thread);//线程继续
pj_thread_sleep(1500);//当前的线程暂停1500毫秒
pj_thread_join(thrad);//等待线程结束
pj_thread_proc函数原型是:intthread_func(void*
argv);
3.对pjlib的thread的线程的封装
1:classCSipThread
2:{
3://1.实现一个int()(void*)的函数,且在结束的地方设置m_thread_t=NULL
4:pj_thread_t*m_thread_t;
5:protected:
6:
7:/*int(pj_thread_proc)(void*);
8:*线程函数;子类需要使用static函数来实现
9:*子类函数中在结束的时候:必须将m_thread_t=NULL;
10:*/
11:pj_thread_proc*m_thread_function;
12:
13:/*这个是实现函数;
14:*子类需要实现一个run()的函数;在run函数中调用run_父类的函数
15:*/
16:virtualvoidrun_(pj_pool_t*pool,pj_thread_proc*function);
17:public:
18:CSipThread();
19:virtual~CSipThread();
20:virtualboolthread_running();
21:
22://等待线程结束,自动释放资源,且会将m_thread_t=NULL
23:virtualvoidthread_join();
24:
25://在线程自己退出的时候,没有需要手工释放资源,和设置m_thread_t=NULL
26:virtualvoidthread_destroy();
27:};
28:CSipThread::CSipThread()
29:{
30:this->m_thread_t=NULL;
31:}
32:CSipThread::~CSipThread()
33:{
34:
35:}
36:voidCSipThread::run_(pj_pool_t*pool,pj_thread_proc*function)
37:{
38:if(this->thread_running())
39:return;
40:pj_status_tstatus=pj_thread_create(pool,"",function,this,
41:PJ_THREAD_DEFAULT_STACK_SIZE,NULL,&this->m_thread_t);
42:if(status!=PJ_SUCCESS)
43:{
44:CFunctions::write_log(LM_ERROR,"Can'tcreatetimerthread.[result=%d]..\n",status);
45:}
46:}
47:boolCSipThread::thread_running()
48:{
49:if(this->m_thread_t==NULL)
50:returnfalse;
51:else
52:returntrue;
53:}
54:
55:voidCSipThread::thread_join()
56:{
57:if(this->m_thread_t==NULL)
58:return;
59:
60://等待线程结束
61:pj_thread_join(this->m_thread_t);
62:}
63:
64:voidCSipThread::thread_destroy()
65:{
66:pj_thread_destroy(this->m_thread_t);
67:this->m_thread_t=NULL;
68:}
4.使用封装起来的thread线程对象
1:/*使用封装后的线程注意事项
2:*1.必须定义一个static的静态函数
3:*2.在静态函数结束的时候必须调用thread_destroy();
4:*/
5:classCSendThread:publicCSipThread
6:{
7://线程函数;在函数退出的时候必须调用thread_destroy();
8:staticintthread_func(void*argv);
9:public:
10:CSendThread(void);
11:virtual~CSendThread(void);
12:
13://再次封装了run_函数
14:voidrun();
15:}
16:
17:voidCSendThread::run()
18:{
19:if(this->thread_running())
20:return;
21:
22:SIP_GUARD(CInterFace::instance()->m_pool_mutex,obj);
23:
24://调用父类的run_函数进行创建函数,开始运行;注意如果线程已经存在,那么直接返回
25://不会再创建一个线程
26:this->run_(CInterFace::instance()->m_pool,&CSendThread::thread_func);
27:}
28:
29:intCSendThread::thread_func(void*argv)
30:{
31://线程函数的参数默认是当前对象,等同于this指针
32:CSendThread*this_thread=(CSendThread*)argv;
33:
34:thread_end:
35://在线程结束的时候,一定要调用thread_destroy();来删除线程
36:this_thread->thread_destroy();
37:return0;
38:}
4.互斥和锁,及其封装(mutex)
pj_mutex_create(this->m_pool,"",PJ_MUTEX_SIMPLE,&this->m_pool_mutex);//创建一个锁指针
pj_mutex_destroy(this->m_pool_mutex);//删除锁指针
pj_mutex_lock(m_mutex);//加锁
pj_mutex_unlock(m_mutex);//解锁
1:/*封装了mutex的使用方法
2:*在创建对象时加锁、删除对象时解锁
3:*/
4:classSip_Lock
5:{
6:pj_mutex_t*m_mutex;
7:public:
8:Sip_Lock(pj_mutex_t*mutex)
9:{
10:this->m_mutex=mutex;
11:pj_mutex_lock(m_mutex);
12:}
13:virtual~Sip_Lock()
14:{
15:pj_mutex_unlock(m_mutex);
16:this->m_mutex=NULL;
17:}
18:};
19:
20:/*封装了sip_lock的使用,直接使用宏定义进行互斥*/
21:#defineSIP_GUARD(MUTEX,OBJ)Sip_LockOBJ(MUTEX);
5.定时器(heap,callback,thread)
//创建定时器堆,设置定时器堆pool大小
pj_timer_heap_create(this->m_pool,MAX_TIMER_COUTN,&this->timer_heap);
pj_timer_heap_set_max_timed_out_per_poll(this->timer_heap,20);
//对定时器加锁是lcok类型
pj_timer_heap_set_lock(this->timer_heap,this->timer_heap_lock,true);
//启动定时器轮询的线程
this->run_(this->m_pool,&CInterFace::timer_thread_fun);
//设置一个定时器
pj_timer_heap_schedule(this->timer_heap,entry,delay);
//取消一个定时器
pj_timer_heap_cancel(this->timer_heap,entry);
//定时器的入口点定义
structpj_timer_entry
{
void*user_data;//定时器的用户数据;C++通常用类对象;C通常用struct
intid;//绝对的ID号;用来区分当user_data和cb都相同的情况
pj_timer_heap_callback*cb;//定时器中的回调函数
};
//定时器回调函数的原型
voidtimer_callback(pj_timer_heap_t*timer_heap,structpj_timer_entry*entry);
一个定时器的使用例子:
1.创建一个定时器、创建一个线程
2.创建一个定时器入口entry
3.创建一个定时器的回调函数,在回调函数中必须重新将entry加入堆中
1://创建定时器堆,设置定时器堆pool大小;加锁;
2:pj_timer_heap_create(this->m_pool,MAX_TIMER_COUTN,&this->timer_heap);
3:pj_timer_heap_set_max_timed_out_per_poll(this->timer_heap,20);
4:pj_timer_heap_set_lock(this->timer_heap,this->timer_heap_lock,true);
5:
6://启动定时器轮询的线程
7:this->run_(this->m_pool,&CInterFace::timer_thread_fun);
8:
9:
10://定时器的线程函数
11:intCInterFace::timer_thread_fun(void*argv)
12:{
13:CInterFace*this_thread=(CInterFace*)argv;
14:intrc;
15:while(!CInterFace::instance()->application_exit())
16:{
17:pj_thread_sleep(1);
18:
19:#ifdefined(PJ_SYMBIAN)&&PJ_SYMBIAN!=0
20:/*OnSymbian,wemustuseOSpoll(ActiveSchedulerpoll)since
21:*timerisimplementedusingActiveObject.
22:*/
23:rc=0;
24:while(pj_symbianos_poll(-1,0))
25:++rc;
26:#else
27:PJ_USE_EXCEPTION;
28:PJ_TRY
29:{
30:rc=pj_timer_heap_poll(CInterFace::instance()->timer_heap,NULL);
31:}
32:PJ_CATCH_ANY
33:{
34:
35:}
36:PJ_END;
37:#endif
38:}
39:
40://定时器轮询的线程退出;必须手工删除pj_thread_t指针,因为它使用了内存池!
41:CFunctions::write_log(LM_DEBUG,"pj_timer_heap_pool,ending.\n");
42:this_thread->thread_destroy();
43:return0;
44:}
45:
46:
47://启动一个定时器:也就是将一个entry添加到堆上面
48:voidCInterFace::start_timer(pj_timer_entry*entry,pj_time_val*delay)
49:{
50:if(!this->thread_running())
51:return;
52:
53:SIP_GUARD(this->timer_heap_mutex,obj);
54:pj_timer_heap_schedule(this->timer_heap,entry,delay);
55:}
56:
57://取消一个定时器:从堆上删除一个entry
58:voidCInterFace::stop_timer(pj_timer_entry*entry)
59:{
60:if(!this->thread_running())
61:return;
62:
63:SIP_GUARD(this->timer_heap_mutex,obj);
64:pj_timer_heap_cancel(this->timer_heap,entry);
65:}
66:
67://启动上报速度和进度的定时器
68:boolCBaseFile::start_timer_speedProgress()
69:{
70:this->m_timer_speed_tval.msec=0;
71:this->m_timer_speed_tval.sec=1;
72:this->m_timer_speed.user_data=this;
73:this->m_timer_speed.cb=&CBaseFile::callback_speed;
74:SIP_GUARD(this->m_run_speed_mutex,obj);
75:this->m_run_speed=true;
76:CInterFace::instance()->start_timer(&this->m_timer_speed,&this->m_timer_speed_tval);
77:returntrue;
78:}
79:
80://取消上报进度和速度的定时器
81:voidCBaseFile::stop_timer_speedProgress()
82:{
83:SIP_GUARD(this->m_run_speed_mutex,obj);
84:this->m_run_speed=false;
85:CInterFace::instance()->stop_timer(&this->m_timer_speed);
86:}
87:
88://上报进度和速度的回调函数
89:voidCBaseFile::callback_speed(pj_timer_heap_t*timer_heap,pj_timer_entry*entry)
90:{
91://上报速度和状态的的
92:if(entry->user_data!=NULL)
93:{
94:CBaseFile*file=(CBaseFile*)entry->user_data;
95:
96:uintspeed_=0;
97:uintprogress_=0;
98:file->get_speed_progress(speed_,progress_);
99:
100:if(file->m_ice_session->is_running())
101:{
102:CInterFace::instance()->report_speed(
103:file->get_userid().c_str(),
104:file->get_fileName().c_str(),
105:file->get_guid(),
106:speed_,
107:progress_);
108:}
109:
110://由于定时select出来后,就从堆上删除了;所以需要一直触发的定时器,
111://就必须在回调函数中,重新想堆中添加entry!
112:SIP_GUARD(file->m_run_speed_mutex,obj);
113:if(file->m_run_speed)
114:CInterFace::instance()->start_timer(entry,&file->m_timer_speed_tval);
115:}
116:}
6.pj_str_t字符串
7.socket的封装和使用
转至:http://www.zhimax.com/article/tcp/pjlib.html
相关文章推荐
- PJSIP简介配置和PJLIB基础库的使用
- PJSIP简介配置和PJLIB基础库的使用
- redis基础简介(八)- redis持久化配置和使用
- redis基础简介(九)- redis虚拟内存的配置和使用
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建
- Sybase ASE 15.03 安装、配置与使用简介
- FPGA软件使用基础之ISE下载配置
- 培训第一天,Java简介,JDK安装,环境配置及Java基础语法
- Spring Cloud Config - RSA简介以及使用RSA加密配置文件
- [使用心得]maven2之m2eclipse使用手册之一简介与配置文件settings.xml
- 大数据实验室(大数据基础培训)——Sqoop的安装、配置及基础使用
- WinDbg配置和使用基础
- WinDbg - 配置和使用基础
- 使用Python管理Azure(1):基础配置
- GIT的SSH配置及使用简介
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)