2.5.1.4 processUaTimerEvent
这个的流程也实在没有什么好说的 , 前面也有了一定的介绍 , 假如大家对这些还有不明白的话 , 可以看一下SIP协议中Trying过程的走势 , 主要是对超时处理部分的介绍 , 就会明白(按照前面所说的UaBuilder::Process中关于SIP命令消息超时的介绍部分) 。
2.5.2 SipThread的Run方法:
Void SipThread::thread()
{
… …
while ( true )
{
try
{
//接收所发送的消息 , 并且预备置入相关的队列中;
Sptr < SipMsgQueue > sipRcv( mySipStack->receive(1000) );
if ( sipRcv != 0 )
{
Sptr < SipMsg > sipMsg = sipRcv->back();
if ( sipMsg != 0 )
{
//根据本地的地址来检查是否发生了路由环路
if ( discardMessage(sipMsg) )
{
continue;
}
// 在这里的myOutputFifo就是 myCallProcessingQueue(异地输入消息的队
//列) , 在Workthread构建的时候会把这个队列带入作为处理参量
Sptr < SipEvent > nextEvent = new SipEvent(myOutputFifo);
if ( nextEvent != 0 )
{
//以下就是把新收到的消息载入队列当中 。
nextEvent->setSipReceive(sipRcv);
nextEvent->setSipStack(mySipStack);
if(myCallLegHistory) nextEvent->setCallLeg();
myOutputFifo->add(nextEvent);
}
}
}
else
{
… …
}
}
catch ( VException& v)
{
… …
}
catch ( ... )
{
… …
}
if ( isShutdown() == true )
{
return;
}
}
}
2.5.2.1 SIP消息的接收/发送缓冲技术
a. 负责接收的主要程序体:
Sptr < SipMsgQueue > sipRcv( mySipStack->receive(1000) );这个方法就是利用SipTransceiver的receive方法接收SIP的消息;
Sptr < SipMsgQueue > SipTransceiver::receive(int timeOut)
{
Sptr < SipMsgQueue > msgQPtr = 0;
//以下是设立超时参数 , 假如发生超时 , 那么就让该命令无效;
timeval start, now;
if ( timeOut >= 0 )
{
gettimeofday(&start, 0);
}
while (msgQPtr == 0)
{
int timePassed = 0;
if ( timeOut >= 0 )
{
gettimeofday(&now, 0);
timePassed = ( now.tv_sec - start.tv_sec ) * 1000
( now.tv_usec - start.tv_usec ) / 1000;
if (timePassed >= timeOut)
{
return 0;
}
}
recvdMsgsFifo.block(timeOut);
if ( !recvdMsgsFifo.messageAvailable() )
{
continue;
}
SipMsgContainer *msgPtr = recvdMsgsFifo.getNext();
if ( msgPtr == 0)
{
assert(0);
cpLog(LOG_CRIT, "received NULL");
continue;
}
#if 1
if ( natOn == true)
{
//这里是一个非常有意思的地方 , 虽然再程序主体中将它设定为False , 也就是我们就
//不能采用NAT转换了 , 不过我还是想介绍一下 , 它主要是用在假如UA是一个标准
//的网关 , 或者是路由器设备的情况之下 , 在这个时候 , 它主要做各个消息包的转
//译工作 , 把路由(Via List)改成下一跳的IP地址和端口地址;
SipVia natVia = msgPtr->msg.in->getVia(0);
LocalScopeAllocator lo;
string addr1 = natVia.getHost().getData(lo);
string addr2 = msgPtr->msg.in->getReceivedIPName().getData(lo);
NetworkAddress netaddr1(addr1);
NetworkAddress netaddr2(addr2);
if ( netaddr1.getHostName() != netaddr2.getHostName())
{
natVia.setReceivedhost(msgPtr->msg.in->getReceivedIPName());
natVia.setReceivedport(msgPtr->msg.in->getReceivedIPPort());
//remove the first item from the via list
msgPtr->msg.in->removeVia(0);
//insert natvia in the vector via list
msgPtr->msg.in->setVia(natVia, 0);
}
}
#endif
//---NAT
推荐阅读
- br软件是干嘛的
- 小孩叛逆期一般在什么年龄段
- 逆向工程技术的发展趋势
- 档案室用什么类型的灭火器
- adobe reader xi如何使用签名文档?
- 湖藕与莲藕的区别 湖藕与莲藕的区别在哪
- 现存老虎的种类有多少种小说中武松在景阳冈上打死的老虎是什么品种的有何依据
- 长虹 M618购机几天来的一些心得
- word中打出下划线具体操作方法
- 蛤蜊油是什么做的,蛤蜊油是什么 蛤蜊油成分 蛤蜊油作用