Chinaunix首页 | 论坛 | 博客
  • 博客访问: 138875
  • 博文数量: 29
  • 博客积分: 2017
  • 博客等级: 大尉
  • 技术积分: 272
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-18 11:23
文章分类

全部博文(29)

文章存档

2011年(11)

2010年(18)

我的朋友

分类: 嵌入式

2011-08-16 12:35:16

最近本人在作关于RTP的项目,要求在arm和pc间用RTP协议传输数据。

1. 下载jrtplib-3.7.1和jthread-1.2.1。

2. pc上编译很简单,windows下编译过程如下:

    首先编译jthread库。然后解压缩jrtplib,打开jrtplib.dsw工程,注意工程的include路径设置,要包含jrtplib和 jthread的头文件,然后编译。将编译生成的jrtplib.lib和jthread.lib拷贝到Microsoft Visual Studio的VC98\Lib目录下。在编译jrtplib.lib和jthread.lib的时候,在project——settings—— C/C++——Code generation:use run-time library中,对于debug,选择:Debug Multithreaded DLL,对于release,则选择:Multithreaded DLL。
??那些example的编译,需要在cpp文件开头加上:
??#pragma comment(lib, "jrtplib.lib")
??#pragma comment(lib, "jthread.lib")
??#pragma comment(lib, "WS2_32.lib")//pragma的作用自己上网查吧
??编译的时候,同样选择编译选项:Debug Multithreaded DLL(对于debug);Multithreaded DLL(对于release)。
??然后在windows上测试example1,这是一个往指定IP的端口上发包的程序,同样也可以收包,测试通过。

   3.jrtplib库的移植,主要参考了这篇文章http://blog.csdn.net/neohuo/archive/2006/03/08/618684.aspx

   编译器我用的arm-linux-gcc3.4.1,2.95.3也用过,不过需要修改一下rtperror里面的代码。可能还有些问题没提到,自己注意 一下吧。

   4.移植成功后,我遇到了第一个棘手的问题,提示can't retrieve login name,建立不了rtpsession。

   后来发现是RTPSession::CreateCNAME这个函数搞得鬼

   这个函数会从系统调用里获取loginname,但是一般的板子由于内核和文件系统的原因都没有loginname,所以

   if (!gotlogin)
 {
  char *logname = getenv("LOGNAME");
  if (logname == 0)
   return ERR_RTP_SESSION_CANTGETLOGINNAME;//这里return了一个error
  strncpy((char *)buffer,logname,*bufferlength);
 }

   所以我强制将logname的值设为root,就ok了。


   5.有些人会遇到arm和pc无法互相接受数据包的问题,但是pc和pc,arm和arm就可以收到。我用sniffer抓了一下包发现确实是有数据包 的,所以应该不是程序的问题。这个问题上网查了一下,也没人说的明白,只有一个高人点了一下,可能是字节序和位域的问题。自己又研究了一下,也是一知半 解。

   一般x86的pc机是用小端字节序(little endian),而嵌入式平台一般是大端字节序(big endian),可能是由于字节序的不同,导致了明明存在数据包,却认不出来的问题。其实,JRTPLIB的开发者可能已经考虑到了这个问题(真牛),在 rtpstructs.h中,有这样的代码定义:

   struct RTPHeader
{
#ifdef RTP_BIG_ENDIAN
 uint8_t version:2;
 uint8_t padding:1;
 uint8_t extension:1;
 uint8_t csrccount:4;
 
 uint8_t marker:1;
 uint8_t payloadtype:7;
#else // little endian
 uint8_t csrccount:4;
 uint8_t extension:1;
 uint8_t padding:1;
 uint8_t version:2;
 
 uint8_t payloadtype:7;
 uint8_t marker:1;
#endif // RTP_BIG_ENDIAN
 
 uint16_t sequencenumber;
 uint32_t timestamp;
 uint32_t ssrc;
};
   这是一个位域结构体,明眼人一下子就看出来了,jrtplib库使用哪种字节序完全取决于RTP_BIG_ENDIAN的定义,这样问题就简单化了。

   我看了一下我编译arm下jrtplib库的rtpconfig_unix.h这个文件,里面果然定义了一个RTP_BIG_ENDIAN,所以要和pc 采用的小端字节序一样,将这个定义取消掉,重新编译库。

   最后运行exmaple1例子,pc 和arm可以互相接受数据包拉!:)这样会引起其他什么问题我还不知道,明天就可以动手编写自己的程序了,呵呵。

阅读(3673) | 评论(1) | 转发(0) |
0

上一篇:JRTPLIB库在Linux平台上的编译

下一篇:没有了

给主人留下些什么吧!~~

hdu1192012-12-20 13:05:50

兄弟,你好,看到你介绍的jrtplib应用。我现在遇到一个问题,在jrtplib的example中,其中example1和example4实例可以实现发送,和接收功能。如果2个例子使用一个IP和端口,则发送接收正常,但发送和接收如果分开使用2个IP就无法实现收。我在linux平台下使用个该库,都是小端模式。另外iptables -F我也去掉了。就是找不到原因...请联系我QQ:7499834,谢谢。