使用openh323开发学习资料.docx
- 文档编号:25610561
- 上传时间:2023-06-10
- 格式:DOCX
- 页数:65
- 大小:35.72KB
使用openh323开发学习资料.docx
《使用openh323开发学习资料.docx》由会员分享,可在线阅读,更多相关《使用openh323开发学习资料.docx(65页珍藏版)》请在冰豆网上搜索。
使用openh323开发学习资料
使用openh323开发
pwlib是一套跨平台的C++的开发库,使基于pwlib上开发的应用能够很少量的移植就可以跑
在windows和unix的平台上.
Open323是澳洲的一家公司驱动的opensource的h323协议族实现,还不够十分的完整,但
是已经是非常的难得了.
在windows上和linux下都能编译使用,我已经试过了.Windows上编译他们比较麻烦,注意
的是一定要用batchbuilding.在VC7上编译openh323的动态连接库的时候,VS.net会崩溃
注意避开,不过也可以试试看看现象,如果能够解决,请告诉我一下.
在linux上编译就没有什么好说的了,设好两个环境变量(PWLIBDIR,OPENH323DIR),就可
以在展开的目录下编译了,先编译PWLIB,再编译OPENH323,别忘了将相应xx/lib写到/et
c/ld.so.conf下.我这里可能对安装讲的不够详细,openh323讲的非常详细,大家可以去
看.
以linux平台为例:
使用pwlib,在成功编译之后,到$(PWLIBDIR)/SAMPLES/
这里是一些例子,hello_world是个非常简单的工程,从这里我们可以看到如何写使用pw
lib的Makefile:
#Simplemakefileforthehelloworldprogram
PROG=hello
SOURCES=hello.cxx
ifndefPWLIBDIR
PWLIBDIR=$(HOME)/pwlib
endif
include$(PWLIBDIR)/make/ptlib.mak
关键是包含了一个ptlib.mak
hello.cxx
#include
classHello:
publicPProcess
{
PCLASSINFO(Hello,PProcess)
public:
voidMain();
};
PCREATE_PROCESS(Hello)
voidHello:
:
Main()
{
cout<<"Helloworld!
\n";
}
非常有代表性.Include$(PWLIBDIR)/make/ptlib.mak这样就可以makeall,makedebu
g的之类的进行编译,需要的头文件库都会替你安排好.编译的结果就会放在obj_linux_x
86_xx,xx表示你用的是debug编译还是其他,如果是debug,xx就是d.
使用pwlib的程序,必然要有一个PProcess的子类,作为整个进程,这是指在console模式
下,gui模式的用PApplication这个我没有用过.Pwlib里面的类大多都是P开头,(可能是
取其兼容的意思,跨平台的特性,我瞎猜的),在进程中如果想创建新的线程就创建PThre
ad子类的对象,对于这种关于过程的类,都有Main函数等待子类去实现.
在使用所有的P类的时候,注意使用两个宏,声明类的时候PCLASSINFO(Hello,PProcess)
;分号可以加,也可不加.PProcess的子类的实现的时候要用PCREATE_PROCESS(Hello);,
这个东西把main()之类的系统入口封装了,由他来调用Main()成员函数.在使用线程的时
候,如果想让线程从线程的对象一创建就运行,就应该在PThread子类中的构造函数中调用
父类的Resume().关于pwlib先说这些,在使用Openh323的时候到处都会用到pwlib的东西
和概念.
Openh323:
终于进入正题了,先粗略的讲点概念(多余了),H323是指协议族了,包含了很多规范,它
来自ITU,应会议的需要而产生,信令相关的东西用H225H245,类似Q931,用ASN1编码后在
tcp之上传输,数据相关的就是编码解码的东西了(包括音频视频),音频g711(alaw,ulaw
)了等等多了,视频h261,好像h263还没实现.
在H323的系统里进行通讯的角色实体就是Endpoint,每个Endpoint可以有很多的Connecti
on,每个Endpoint也可以拥有很多的逻辑角色,这个不讨论.
Endpoint在Openh323中就是类H323Endpoint的实例
Connection在Openh323中就是H323Connection的实例
当Endpoint接收了一个远程的连接请求,Endpoint就会创建一个H323Connection;
当Endpoint发出一个连接的请求,Endpoint也会创建一个H323Connection
Connection就会进入一个状态机,在各个状态中,Connetcion会相应的执行相应的方法,
这些方法,大多都是Onxxxxx(),是虚函数,我们可以自己通过继承H323Connection创建
其子类,并且在我们想做事的时机去重载相应的虚函数.这是使用Openh323的一个基本的
思路.
现在我们可以看看如何写一个自己H323的Endpoint,让它能够和netmeeting互操作.成功编
译Openh323后在它的samples的目录下面有几个例子,mfc是指在windows下如何使用MFC和
Openh323一起开发,还有simple,这是个简单的H323的Endpoint的实现,作为理解OpenH3
23的库如何使用和开发的技巧方法已经足够了.
程序运行主线:
PWLIB(PCREATE_PROCESS(SimpleH323Process))--SimpleH323Process:
:
SimpleH
323Process()--SimpleH323Process:
:
Main();
Main()如果结束,这个程序就结束了,可是Main()里面有个死循环,写过图形程序的朋友
们都知道,这就是在等消息来呀.在VC中称之为Interfacethread.
程序注解:
main.h
这个文件包含了程序用到的所有类的声明,一般应该至少有三个类:
来自PProcess的一个主进程的,或者说作为界面线程的;(只有一个对象)
来自H323Endpoint的,标识这个H323端点的;(只有一个对象)
来自H323Connection的,标识所有和这个H323端点相关的连接;(可以有多个)
#ifndef_SimpleH323_MAIN_H
#define_SimpleH323_MAIN_H
//避免头文件重复包含
#include
classSimpleH323EndPoint:
publicH323EndPoint
{
//使用Pwlib的要求,就像使用MFC,有n多的宏,可以看看pwlib的源码,
//宏展开都干了什么
PCLASSINFO(SimpleH323EndPoint,H323EndPoint);
public:
SimpleH323EndPoint();
~SimpleH323EndPoint();
//overridesfromH323EndPoint
//重载H323EndPoint的函数
//当收到一个远程的呼入和发出呼出的请求的时候
virtualH323Connection*CreateConnection(unsignedcallReference);
//有远程的请求来到,这是在CreateConnection之后的
virtualBOOLOnIncomingCall(H323Connection&,constH323SignalPDU&,H323Signa
lPDU&);
//应答远程的呼入
virtualH323Connection:
:
AnswerCallResponseOnAnswerCall(H323Connection&,cons
tPString&,constH323SignalPDU&,H323SignalPDU
&);
//当连接被Forward
virtualBOOLOnConnectionForwarded(H323Connection&,constPString&,constH3
23SignalPDU&);
//当连接建立
virtualvoidOnConnectionEstablished(H323Connection&connection,constPStrin
g&token);
//当连接撤销
virtualvoidOnConnectionCleared(H323Connection&connection,constPString&
clearedCallToken);
//当连接需要打开声音的通道
virtualBOOLOpenAudioChannel(H323Connection&,BOOL,unsigned,H323AudioCodec
&);
//Newfunctions
//自己添加的新函数,父类中不存在
BOOLInitialise(PArgList&);
BOOLSetSoundDevice(PArgList&,constchar*,PSoundChannel:
:
Directions);
//每个连接会有一个Token来唯一标识
PStringcurrentCallToken;
protected:
BOOLautoAnswer;
PStringbusyForwardParty;
};
classSimpleH323Connection:
publicH323Connection
{
PCLASSINFO(SimpleH323Connection,H323Connection);
public:
//创建连接对象的时候将Endpoint的对象以引用传进来
//引用的概念就是将整个对象暴露给你的意思,不是复制了一份的意思,
//对象还是原来的对象,所以在Connection中修改了EndPoint的某些属性后
//就是在操作着传进来的对象,这是C++的基本概念,OpenH323大量的使用
//引用传递对象,对引用的概念要理解
SimpleH323Connection(SimpleH323EndPoint&,unsigned);
//重载了两个父类的函数
//当打开逻辑通道的时候(等于没说)
virtualBOOLOnStartLogicalChannel(H323Channel&);
//处理用户输入,这个不是之运行这个程序的用户,而是这个连接上的用户输入
//一般应该是拨号了之类的,
virtualvoidOnUserInputString(constPString&);
protected:
//快速连接?
?
BOOLnoFastStart;
};
classSimpleH323Process:
publicPProcess
{
//主进程,类似VC的用户界面线程,
//他是整个程序的入口点,和结束点
//创建了EndPoint对象后会有好几个线程启动
//这个就是主线程
PCLASSINFO(SimpleH323Process,PProcess)
public:
SimpleH323Process();
~SimpleH323Process();
//这个函数会被自动调用,是我们程序的入口了
voidMain();
protected:
//这个H323端点对象
SimpleH323EndPoint*endpoint;
};
#endif//_SimpleH323_MAIN_H
下面是main.cpp所有的类的实现了
#include
#ifdef__GNUC__
#defineH323_STATIC_LIB
#endif
#include"main.h"
#include"../../version.h"
#definenewPNEW
//这个东西里边可能封装了标准的main函数
PCREATE_PROCESS(SimpleH323Process);
///////////////////////////////////////////////////////////////
//几个宏都在version.h里面定义
SimpleH323Process:
:
SimpleH323Process()
:
PProcess("OpenH323Project","SimpleH323",
MAJOR_VERSION,MINOR_VERSION,BUILD_TYPE,BUILD_NUMBER)
{
endpoint=NULL;
}
SimpleH323Process:
:
~SimpleH323Process()
{
deleteendpoint;
}
voidSimpleH323Process:
:
Main()
{
cout< <<"Version"< <<"by"< <<"on"< <<"("< //Getandparseallofthecommandlinearguments. //分析命令行参数,略去数行 PArgList&args=GetArguments(); args.Parse( "a-auto-answer." "b-bandwidth: " "B-forward-busy: " "D-disable: ”FALSE); if(args.HasOption(h)||(! args.HasOption(l)&&args.GetCount()==0)){ //如果没有参数或者参数是h,就输出如何使用,此处略去数行 } //这个东西暂时不管 #ifPTRACING #endif //CreatetheH.323endpointandinitialiseit //H323EndPoint创建了,并且把命令参数传过去初始化,初始化的时候做了一些事 endpoint=newSimpleH323EndPoint; if(! endpoint->Initialise(args)) return; //看看命令行里是不是想直接呼叫另一个H323的endpoint.有没有l(listen)的option //如果是就MakeCall, //Seeifmakingacallorjustlistening. if(args.HasOption(l)) cout<<"Waitingforincomingcallsfor\""< "\"\n"; else{ cout<<"Initiatingcallto\""< endpoint->MakeCall(args[0],endpoint->currentCallToken); } cout<<"PressXtoexit."< //Simplestpossibleuserinterface //简单的用户界面,会有一个提示> //取pid是我加的 for(;;){ pid_tthispid; charprom[20]; thispid=getpid(); sprintf(prom,"H323%d>",thispid); cout< PCaselessStringcmd; cin>>cmd; if(cmd=="X") break; if(cmd.FindOneOf("HYN")! =P_MAX_INDEX){ H323Connection*connection; //使用lock就是怕别的线程把它给删了 //因为这里正用着呢 connection=endpoint->FindConnectionWithLock(endpoint->currentCallToken); if(connection! =NULL){ if(cmd=="H") connection->ClearCall(); elseif(cmd=="Y") connection->AnsweringCall(H323Connection: : AnswerCallNow); elseif(cmd=="N") connection->AnsweringCall(H323Connection: : AnswerCallDenied); connection->Unlock(); } } } cout<<"Exiting"< } //Main函数结束 //自己的Init函数 BOOLSimpleH323EndPoint: : Initialise(PArgList&args) { //Getlocalusername,multipleusesof-uindicatesadditionalaliases if(args.HasOption(u)){ PStringArrayaliases=args.GetOptionString(u).Lines(); //设定改Endpoint的username SetLocalUserName(aliases[0]); //设定Aliases就是每个Endpoint可以有好多名字的意思 for(PINDEXi=1;i AddAliasName(aliases[i]); } //Setthevariousoptions //设置静音检测否 SetSilenceDetectionMode(args.HasOption(e)? H323AudioCodec: : NoSilenceDetection : H323AudioCodec: : AdaptiveSilenceDetection); //快速连接? DisableFastStart(args.HasOption(f)); //H245通道 DisableH245Tunneling(args.HasOption(T)); autoAnswer=args.HasOption(a); busyForwardParty=args.GetOptionString(B); if(args.HasOption()){ initialBandwidth=args.GetOptionString().AsUnsigned()*100; if(initialBandwidth==0){ cerr<<"Illegalbandwidthspecified."< returnFALSE; } } if(args.HasOption(j)){ unsignedjitter=args.GetOptionString(j).AsUnsigned(); //设定音频抖动的,应该影响到接收的缓存 if(jitter>=20&&jitter<=10000) SetMaxAudioDelayJitter(jitter); else{ cerr<<"Jittershouldbebetween20millisecondsand10seconds."< returnFALSE; } } //设定声音设备 //也可以不用声音设备,比如Openh323工程的子项目OpenAM和OpenMCU //都使演示了如何不使用声音物理设备的方法,我想那里边的东西会对某些朋友们 //的需求比较合适 if(! SetSoundDevice(args,"sound",PSoundChannel: : Recorder)) returnFALSE; if(! SetSoundDevice(args,"sound",PSoundChannel: : Player)) returnFALSE; if(! SetSoundDevice(args,"sound-in",PSoundChannel: : Recorder)) returnFALSE; if(! SetSoundDevice(args,"sound-out",PSoundChannel: : Player)) returnFALSE; //设定decodeencode的能力 //H323EndPoint在真正进行数据通讯之前要进行能力的交换,说明自己能够接收和发送 什么标准的数据,g.711是必须支持的. //Setthedefaultcodecsavailableonsoundcards. AddAllCapabilities(0,0,"GSM*{sw}"); AddAllCapabilities(0,0,"G.711*{sw}"); AddAllCapabilities(0,0,"LPC*{sw}"); AddAllUserInputCapabilities(0,1); RemoveCapabilities(args.GetOptionString(D).Lines()); ReorderCapabilities(args.GetOptionString(P).Lines()); cout<<"Localusername: "< <<"Silenceco
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 使用 openh323 开发 学习 资料
![提示](https://static.bdocx.com/images/bang_tan.gif)