libpcap抓lidar数据保存的那些事

一、 下载及编译libpcap

1) 在网上下载libpcap,我下载的是libpcap-1.8.1.tar.gz,
2) 解压缩,执行tar xvzf libpcap-1.8.1.tar.gz
3) cd到libpcap-1.8.1目录,打开configure文件,将下面三行注释掉:

  • #if test -z “KaTeX parse error: Expected 'EOF', got '&' at position 12: with_pcap" &̲& test "cross_compiling” = yes; then

    { { echo “ a s m e : as_me: asme:LINENO: error: pcap type not determined when cross-compiling; use --with-pcap=…” >&5

    #fi
    4) 执行sudo ./configure --host=arm-linux --with-pcap=linux 生成Makefile文件
    如果在生成Makefile过程出现以下问题:
    Your operating system’s lex is insufficient to compile libpcap
    安装:yum -y install flex 、 yum -y install bison 、sudo apt-get install flex
    5) 如果第四步执行成功,会生成一个Makefile文件,将Makefile文件中:
    CC=gcc改成CC=arm-linux-gcc
    6)make,完成之后会生成两个库文件编译完成后在libpcap-1.8.1目录里面会生成libpcap.a静态库和libpcap.so.1.8.1动态库。这两个库就是我们所需要的
    7)在x86编译程序时加上-lpcap连接libpcap库,
    8)将libpcap.so.1.8.1拷到arm板上/lib中,再建立两个软连接
    In -s libpcap.so.1.8.1 libpcap.so.1
    In -s libpcap.so.1 libpcap.so

二、 libpcap库使用

1) 函数名称:char *pcap_lookupdev(char *errbuf)
函数功能:用于返回可被pcap_open_live()或pcap_lookupnet()函数调用的网络设备名指针。参数说明:如果函数出错,则返回NULL,同时errbuf中存放相关的错误消息。
2)函数名称:pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char ebuf)
函数功能:获得用于捕获网络数据包的数据包捕获描述字。
参数说明:device 参数为指定打开的网络设备名。snaplen参数定义捕获数据的最大字 节数。promisc指定是否将网络接口置于混杂模式。to_ms参数指
定超时时 间(毫秒)。ebuf参数则仅在pcap_open_live()函数出错返回NULL时用于传递错误消息。
3)函数名称:pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname)
函数功能:打开用于保存捕获数据包的文件,用于写入。
参数说明:fname 参数为”-“时表示标准输出。出错时返回NULL。p参数为调用pcap_open_offline()或pcap_open_live()函数后返回的 pcap结构指针。fname参数指定打开的文件名。如果返回NULL,则可调用pcap_geterr()函数获取错误消息。
4)函数名称:int pcap_loop(pcap_t *p, int cnt,pcap_handler callback, u_char *user)
函数功能: 功能基本与pcap_dispatch()函数相同,只不过此函数在cnt个数据包被处理或出现错误时才返回,但读取超时不会返回。而如果为 pcap_open_live()函数指定了一个非零值的超时设置,然后调用pcap_dispatch()函数,则当超时发生时 pcap_dispatch()函数会返回。cnt参数为负值时pcap_loop()函数将始终循环运行,除非出现错误。
5)函数名称:void pcap_dump(u_char *user, struct pcap_pkthdr *h,u_char *sp)
函数功能:向调用pcap_dump_open()函数打开的文件输出一个数据包。该函数可作为pcap_dispatch()函数的回调函数。
6)函数名称:void pcap_dump_close(pcap_dumper_t *p)
函数功能:关闭相应的被打开文件。

在Ags310程序上就只用到以上几个函数,之前的ags310程序对lidar数据的接收处理是:先开辟一个缓冲区,把从recvfrom函数收的数据拷贝到缓冲区中,对lidar数据存盘处理:先从缓冲区中读出来,然后再写到文件中去。
现在Ags310的程序是利用pcap_loop()函数进行循环抓包,抓到包之后跳用回调函数,在回调函数将数据写入(pcap_dump)文件中,写入200
1024包之后,关闭文件再新建一个 这个方案的结果就是写人文件(同时写SD和EMMC)204800包需要146s,理论时间是122.2s,出现丢包很严重。
这个方案经过实际验证实行不的,我们的开发板是Cortex-A5的,工作频率最高500MHZ,雷神16线激光雷达的数据是0.6ms一包,一包是1248个字节,大概就是2M/s的数据,在程序开辟一个大的缓冲区,等收到3000包,就写一次文件
*

部分程序

devstr = pcap_lookupdev(errBuf);    //找到一个网络设备,返回一个char型针针   
if(devstr)
{
	printf("success:device :%s/n",devstr);
}
m_pHandle = pcap_open_live(devstr,65535,1,0,errBuf);//打开一个网络设备,返回捕获网络数据包的描述字
if(!m_pHandle)
{
	printf("error:pcap_open_live():%s\n",errBuf);
}
char pszFilepath[MAX_PATH] = {0};
sprintf(pszFilepath,"/mnt/sd/lidar_%d.pcap",m_nFileIndex);
	m_pDumpOpen = pcap_dump_open(m_pHandle,pszFilepath);//打开一个.pcap文件,返回文件描述符

pcap_loop(pThis->m_pHandle,-1,getPacket,(u_char *)&id); //循环抓包

回调函数**

void CLidarProcess::getPacket(u_char *args,const struct pcap_pkthdr *pkthdr,const u_char *packet)
{
static i4 i4RecvCount = 0;
g_bLidarNetRecvStatusFlag = true;			
if(true == g_bPPSGetGpsTimeFlag) //是否同步
{
if(DEFAULT_PACAP_PACK_NUM <= m_pLidarProcess->m_PcakNum)
{  //判断是否超过200*1024个包
	struct tm *p;
	struct timeval current_cpu_time; 
	gettimeofday(&current_cpu_time, NULL);
	p = gmtime(&(current_cpu_time.tv_sec));		
	m_nFileIndex++; //文件索引加1
	m_pLidarProcess->m_PcakNum = 0; //包数清零
	pcap_dump_close(m_pLidarProcess->m_pDumpOpen);//关闭文件
	m_pLidarProcess->m_pDumpOpen = NULL;
	char pszFilePath[MAX_PATH] = {0};
	sprintf(pszFilePath,"/mnt/sd/lidar_%d%02d%02d%02d%02d%02d_%d.pcap",(1900 + p->tm_year), (1 + p->tm_mon),  p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec,m_nFileIndex);
m_pLidarProcess->m_pDumpOpen=  pcap_dump_open(m_pLidarProcess->m_pHandle,pszFilePath);//重新打开一个文件
	if(NULL == m_pLidarProcess->m_pDumpOpen)
	{
		printf("open file failed\n");
		return ;		
	}
}
pcap_dump((u_char *)m_pLidarProcess->m_pDumpOpen,pkthdr,packet);//将数据包写入文件中
	m_pLidarProcess->m_PcakNum++; //包数加1
}

关于libpcap库函数的详细解释请参考博客:
https://blog.csdn.net/u012592081/article/details/47047237

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值