LINUX编程实战指发送UDP消息

news/2024/7/7 8:51:21

最近调试媒体服务器,发现被叫的媒体流总是抖动的厉害,不清楚是网络原因还是媒体服务器的代码问题。

为了方便排查问题,我编写了一个UDP发送的小工具。根据传入目的地的IP、PORT和发送的时长。该工具就可以按照20ms的间隔进行重复发送RTP流。

编程思路:

首先初始化本端udp的socket套接字:

memset(buf,1,sizeof(buf));
	char * desip = argv[1];
	int destport = atoi(argv[2]);
	int sec = atoi(argv[3]);
	int count = sec * 1000 / 20;
	int fd=-1;
  fd=socket(AF_INET,SOCK_DGRAM,0);
  fcntl(fd,F_SETFL,O_NDELAY);
  int reuse_addr_flag=1;
  int success=setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&reuse_addr_flag,sizeof(reuse_addr_flag));
  if(success<0)
  {
      perror("udp setsockopt(SO_REUSEADDR): ");
      close(fd);
      return 0;
  }
   int sendBufSize,sendBufLength;
   sendBufSize=4*1024*1024;
   sendBufLength=sizeof sendBufSize;

   if(setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(char*)&sendBufSize,sendBufLength)<0)
   {
      perror("udp setsockopt(SO_SNDBUF): ");
      return 0;
   }
   if(setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(char*)&sendBufSize,sendBufLength)<0)
   {
      perror("udp setsockopt(SO_RCVBUF): ");
      return 0;
   }
   struct sockaddr_in localaddr;
   in_addr_t net_addr=inet_addr("0.0.0.0");
   //ntohl(l_ipv4.ip_dw)
	 memset(&localaddr,0,sizeof(struct sockaddr_in));
	 localaddr.sin_family = AF_INET;
	 localaddr.sin_port = 30008;
	 memcpy((struct sockaddr*)&localaddr.sin_addr,(void *)(&net_addr),sizeof(net_addr));
	 if (bind(fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr_in)) != 0)
	 {
		return 0;
	 }

根据目的端的IP、PORT设置套接字:

int success;
   struct sockaddr *pDestAddr = NULL;
   struct sockaddr_in destAddr;
   int len;
   memset(&destAddr,0,sizeof(struct sockaddr_in));
   in_addr_t net_addr=inet_addr(host);
   destAddr.sin_family = AF_INET;            
   destAddr.sin_port = htons(port);
   memcpy((struct sockaddr*)&destAddr.sin_addr,(void *)(&net_addr),sizeof(net_addr));
   pDestAddr = (struct sockaddr*)&destAddr;
   len = sizeof(destAddr);

最后调用sendto函数,发送UDP数据

success = sendto(fd,buffer,length,0, pDestAddr, len);
   if(success<0)
   {
      char *buf = new char[length + 128];
      sprintf(buf, "sendto(%d, %s, %d, %s, %d):", fd, buffer, length, host, port);
      perror(buf);
      delete []buf;
   }

完整的代码如下:

#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h> 
#include <signal.h>
#include <unistd.h>

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

void sendUDPMsg(int fd,char* host,unsigned short port,char* buffer,int length);
int main(int argc,char* argv[])
{
	char buf[640]={1};
	memset(buf,1,sizeof(buf));
	char * desip = argv[1];
	int destport = atoi(argv[2]);
	int sec = atoi(argv[3]);
	int count = sec * 1000 / 20;
	int fd=-1;
  fd=socket(AF_INET,SOCK_DGRAM,0);
  fcntl(fd,F_SETFL,O_NDELAY);
  int reuse_addr_flag=1;
  int success=setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&reuse_addr_flag,sizeof(reuse_addr_flag));
  if(success<0)
  {
      perror("udp setsockopt(SO_REUSEADDR): ");
      close(fd);
      return 0;
  }
   int sendBufSize,sendBufLength;
   sendBufSize=4*1024*1024;
   sendBufLength=sizeof sendBufSize;

   if(setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(char*)&sendBufSize,sendBufLength)<0)
   {
      perror("udp setsockopt(SO_SNDBUF): ");
      return 0;
   }
   if(setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(char*)&sendBufSize,sendBufLength)<0)
   {
      perror("udp setsockopt(SO_RCVBUF): ");
      return 0;
   }
   struct sockaddr_in localaddr;
   in_addr_t net_addr=inet_addr("0.0.0.0");
   //ntohl(l_ipv4.ip_dw)
	 memset(&localaddr,0,sizeof(struct sockaddr_in));
	 localaddr.sin_family = AF_INET;
	 localaddr.sin_port = 30008;
	 memcpy((struct sockaddr*)&localaddr.sin_addr,(void *)(&net_addr),sizeof(net_addr));
	 if (bind(fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr_in)) != 0)
	 {
		return 0;
	 }
	 
	 int i =0;
	 for(i=0;i<count;i++)
	 {
	 	 sendUDPMsg(fd,desip,destport,buf,sizeof(buf));
	 	 usleep(1000 * 20);
	 }
	 return 1;
}

void sendUDPMsg(int fd,char* host,unsigned short port,char* buffer,int length)
{   
   int success;
   struct sockaddr *pDestAddr = NULL;
   struct sockaddr_in destAddr;
   int len;
   memset(&destAddr,0,sizeof(struct sockaddr_in));
   in_addr_t net_addr=inet_addr(host);
   destAddr.sin_family = AF_INET;            
   destAddr.sin_port = htons(port);
   memcpy((struct sockaddr*)&destAddr.sin_addr,(void *)(&net_addr),sizeof(net_addr));
   pDestAddr = (struct sockaddr*)&destAddr;
   len = sizeof(destAddr);
   success = sendto(fd,buffer,length,0, pDestAddr, len);
   if(success<0)
   {
      char *buf = new char[length + 128];
      sprintf(buf, "sendto(%d, %s, %d, %s, %d):", fd, buffer, length, host, port);
      perror(buf);
      delete []buf;
   }
}

代码编译方法如下:

g++ -g testrtpudp.c -o testrtp

使用方法如下:

./testrtp 192.168.2.77 3950 1


http://www.niftyadmin.cn/n/3336791.html

相关文章

ioctl--字符设备的控制技术【转】

本文转载自&#xff1a;http://blog.csdn.net/coding__madman/article/details/51356313 字符设备的控制 1. 字符设备控制理论 1.1 作用 大部分驱动程序除了需要提供读写设备的能力外&#xff0c;还需要具备控制设备的能力。比如&#xff1a;改变波特率 1.2 应用程序接口 在用户…

linux中oops信息的调试及栈回溯【转】

本文转载自&#xff1a;http://blog.csdn.net/kangear/article/details/8217329 原文地址&#xff1a;http://blog.micro-studios.com/?p615#comment-1069 看后感想&#xff1a;這点比 ldd3上讲的都仔细 2012年11月29日11:24:17&#xff1a;有BUG_ON就不用反汇编了。。。 201…

如何关闭CenOS/RedHat的X Windows

因为要安装CUDA驱动&#xff0c;CUDA驱动不能X Windows下安装&#xff0c;所以搜索关闭X Windows的方法。 现在总结如下&#xff1a; root用户使用init 3&#xff0c;切换到命令行模式&#xff1b; root用户使用init 5,切换到X Windows图形界面模式

总线设备驱动模型【转】

本文转载自&#xff1a;http://blog.csdn.net/coding__madman/article/details/51428400 总线驱动设备模型&#xff1a; 1. 总线设备驱动模型概述 随着技术的不断进步&#xff0c;系统的拓扑结构也越来越复杂&#xff0c;对热插拔&#xff0c;跨平台移植性的要求也越来越高&…

混杂设备动态次设备号分析【转】

本文转载自&#xff1a;http://blog.csdn.net/yongan1006/article/details/6778285 今天看驱动源码时&#xff0c;发现一个MISC_DYNAMIC_MINOR宏&#xff0c;于是分析了一下内核源码。先粘出源码。在misc_register函数中&#xff0c;有如下语句&#xff1a; if (misc->minor…

Linux的fasync驱动异步通知详解【转】

本文转载自&#xff1a;http://blog.csdn.net/coding__madman/article/details/51851338 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 工作项目用有个需求是监测某个GPIO输入方波的频率&#xff01;通俗的讲就是一个最最简单的测方波频率的示波…

如何将.m4a转.wav文件

昨天现场交付的同事找到我&#xff0c;想把一个.m4a格式的文件转为.wav文件&#xff0c;目的是可以使得现场的媒体服务器将语音播放出来。 我习惯性的打开了adobe audition文件打开语音进行转换&#xff0c;但是该软件提示找不到acc.dll文件。我下载acc.dll文件后&#xff0c;通…

GPIO口及中断API函数【转】

本文转载自&#xff1a;http://blog.sina.com.cn/s/blog_a6559d9201015vx9.htmlG #include <linux/gpio.h> // 标准 GPIO_API int gpio_request(unsigned gpio, const char *label); 获得并占有 GPIO port 的使用权&#xff0c;由参数 gpio 指定具体 port&#xff0c;非空…