Chinaunix首页 | 论坛 | 博客
  • 博客访问: 624482
  • 博文数量: 116
  • 博客积分: 6078
  • 博客等级: 准将
  • 技术积分: 1214
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-23 10:09
文章分类

全部博文(116)

文章存档

2016年(1)

2015年(4)

2011年(2)

2010年(21)

2009年(88)

分类: C/C++

2009-06-03 15:45:28

/********************此文可以被转发,但请转发者保留作者的署名权
****李浩
****msn:lihao_nx@hotmail.com
****
****email:lihaoyxj@gmail.com
****出处:lihaoyxj.cublog.cn

*****************/

例子为5rd中的,而帮助为3rd,有一些接口在3rd帮助中是没有的,而针对RTP传输在SYMBIAN上我也没做过,现在只是整理,待后边验证,如果有什么错再改
假设要连接的相关参数为
远程IP:92.168.0.6
远程端口: 8000
本地端口: 7000
包大小:4096,分析NOKIA的RTP例子
1. 以Udp初始化RhostResolver,并获取与远程地址的一个连接
        RHostResolver resolver;
    User::LeaveIfError(resolver.Open(iSockServ,KAfInet,KProtocolInetUdp));
    CleanupClosePushL(resolver);
    TNameEntry entry;
    TRequestStatus status;
    resolver.GetByName(KDestAddr,entry,status);
    User::WaitForRequest(status);
    User::LeaveIfError(status.Int());
    CleanupStack::PopAndDestroy(1);//close resolver

    TSockAddr remote = entry().iAddr;
    remote.SetPort(dport);
2. 创建一个本地连接地址
        TInetAddr localAddr;
    localAddr.SetPort(iLocalPort);
3. 创建一个本地的SOCKET并创建一个RTCP
        User::LeaveIfError(iSocket.Open(iSocketServ, KAfInet,KSockDatagram, KProtocolInetUdp));    
    User::LeaveIfError(iSocket.Bind(localAddr));
    localAddr.SetPort(iLocalPort + 1);
    User::LeaveIfError(iRtcpSocket.Open(iSocketServ, KAfInet,KSockDatagram, KProtocolInetUdp));    
    User::LeaveIfError(iRtcpSocket.Bind(localAddr));
4. 本地socket连到到用程,并用rtpsession打开它,同时打开rtcp
    TRequestStatus stat;
    iSocket.Connect(iDestAddr,stat);
    User::WaitForRequest(stat);
    User::LeaveIfError(stat.Int());
    iDestAddr.SetPort(iDestAddr.Port() + 1);
    iRtcpSocket.Connect(iDestAddr,stat);
    User::WaitForRequest(stat);
    User::LeaveIfError(stat.Int());
    iRtpSession.OpenL(iSocket, aPacketSize+12, iRtcpSocket);
5. 后边有一个没查出功能的
        iRtpSession.SetRTPTimeConversion(100, 100);
6. 注册RTP回调
        iRtpSession.PrivRegisterEventCallbackL(ERtpNewSource, (TRtpCallbackFunction)CRtpFileStreamer::NewSource, this);
   在此处注册后就可以处理收到的信息,处理接口如下:
    void CRtpFileStreamer::NewSource(CRtpFileStreamer* aPtr, const TRtpEvent& aEvent)
    {
    if (aPtr->ReceiveSrc().IsOpen())
        {
        aPtr->ReceiveSrc().Close();
        }
    TRAPD(err,
        aPtr->ReceiveSrc() = aEvent.Session().NewReceiveSourceL();
        aPtr->ReceiveSrc().PrivRegisterEventCallbackL(ERtpPacketReceived, (TRtpCallbackFunction)CRtpFileStreamer::PacketArrived, aPtr);)
    if (err!=KErrNone)
        {
        __DEBUGGER();
        }
    }
   
/**
A callback method that is called on packet arrival.
*/   
void CRtpFileStreamer::PacketArrived(CRtpFileStreamer* aPtr, const TRtpEvent& aEvent)
    {   
    aPtr->iRecvPacket.Close();
    aPtr->iRecvPacket = aEvent.ReceiveSource().Packet();
    if (aEvent.ReceiveSource().Packet().IsOpen())
        {
        __DEBUGGER();
        }
    TRAPD(err,aPtr->HandleReceivedPacketL());
    if (err!=KErrNone)
        {
        __DEBUGGER();
        }
    }
7. 现在需要创建一个RRtpSendPacket
    RRtpSession&    iSession;
    RRtpSendSource    iSendSrc;
    RRtpSendPacket    iSendPacket;
        iSendSrc = iSession.NewSendSourceL();
    iSendSrc.SetDefaultPayloadSize(iPacketSize);
    
    iSendSrc.PrivRegisterEventCallbackL(ERtpSendSucceeded, (TRtpCallbackFunction)CRtpFileSender::PacketSent, this);
    iSendSrc.PrivRegisterEventCallbackL(ERtpSendFail, (TRtpCallbackFunction)CRtpFileSender::SendError, this);

    iSendPacket = iSendSrc.NewSendPacketL();
8. 现在可以通过iSendPacket来进行数据发送了
    TInt tmp = iPayloadDesC.Length();
    iSendPacket.WritePayload().SetLength(tmp);
    iSendPacket.Send();
9. 由于这个是一个读文件并传输的,故内存区域是固定的
        iPayloadDesC.Set(const_cast(iSendPacket.WritePayload().Ptr()),iPacketSize,iPacketSize);
    User::LeaveIfError(iFile.Read(iPayloadDesC));
10. 发送结束后的清理工作
        iSendPacket.Close();
    iSendSrc.Close();
        iRtpSession.Close();
    iSocket.Close();
    iRtcpSocket.Close();
    iSockServ.Close();
 
阅读(1536) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-06-13 16:00:00

谢谢你的解释!具体应用,我在想想!

lihao_nx2009-06-13 11:48:03

我所理解到的,rtp在进行传输时加时戳和其它标号可以在传输时确认数据完整性,但是是否发送成功这个问题,在udp中是不能处理的,因为在采集时,假设我们可以在发送方为30帧每秒,但是接收方你往往看到的有时是停顿在那,可能几秒才会出一帧。而传输是否有效或数据是否可以为对方所接收则同rtcp协议来完成,一般是60秒来完成一次RTCP传输,从而确认网络质量等

chinaunix网友2009-06-13 08:44:49

lihao哥,小弟初次接触rtp,有个很菜的问题想问你一下。 在Symbian下模拟器或真机中,当我用rtp协议向服务器发送数据后,我如何判定我发送数据成功和数据完整正确性!