linux udp socket编程实例

1:udp通信框图


在上面的客户端,也是可以执行bind()和connect操作的,在下面的客户端代码中,我们是这么来实现的。

2:udp server端代码

#if 1
#include "./../../udp_client/src/iolib/iolib.h" /* 添加用户自已的I/O函数库 */
#define MAX_LINE 100
//extern int checkSelect(int handfd,char *rwflag);
void my_fun(char * p)
{
	if(p == NULL) /* 空串 */
		return;

	for (; *p != '\0'; p++)
		if(*p >= 'A'&& *p <= 'Z')
			*p = *p -'A'+ 'a';
}
int getUdpServerSocketId(int argc, char *argv[])
{

	struct sockaddr_in servaddr;
	int sockfd;
	if (argc != 3)
	{
		fputs("usage: ./client serverIp serverPort\n", stderr);
		exit(1);
	}
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd == -1)
	{
		perror("create udp socket....\n");
	}
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(atoi(argv[2]));
	inet_aton(argv[1], &servaddr.sin_addr.s_addr);
	if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
	{
		printf("set ip address error!\n");
		exit(0);
	}
 	if(bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) == -1)
 	{
		perror("call to bind");
     	exit(1);
	}
 	return sockfd;
}
int main(int argc, char *argv[])
{
    	struct sockaddr_in clientaddr;
    	int s_fd,i=0,found=0;;
		  socklen_t addr_len,sndAddrLen;
    	char buf[MAX_LINE];
    	char addr_p[INET_ADDRSTRLEN];
    	int n;
    	s_fd = getUdpServerSocketId(argc,argv);

     	while (1)
     	{
          	memset(buf,0,MAX_LINE);
          	sndAddrLen = addr_len = sizeof(clientaddr);
           	n = recvfrom(s_fd, buf, MAX_LINE, 0, (struct sockaddr *) &clientaddr, &addr_len);
           	if (n == -1)
           	{
           		perror("fail to receive\n");
           		exit(1);
           	}
           	else
           	{
       			  printf("received from %s at PORT %d\n",inet_ntop(AF_INET, &clientaddr.sin_addr, addr_p, sizeof(addr_p)),ntohs(clientaddr.sin_port));
							printf("content is :len:%d %s\n",n, buf);
							my_fun(buf);
							while(i++<5)
							{
								n = sendto(s_fd, buf, n, 0, (struct sockaddr *) &clientaddr, sndAddrLen);
								if (n == -1)
								{
									perror("fail to send\n");
									exit(1);
								}
								sleep(2);
							}
							i=0;
           	}
		}

		if(close(s_fd) == -1)
		{
			perror("fail to close");
			exit(1);
		}
	return 0;
}
#endif

3:udp client端代码

#include "./iolib/iolib.h" /* 添加用户自已的I/O函数库 */
#define MAX_LINE 80
int getUdpClietnSocketId(int argc, char *argv[])
{
	struct sockaddr_in servaddr,clientaddr;
	int sockfd;
#if 0
	if (argc != 4)
	{
		fputs("usage: ./client serverIp serverPort localIp\n", stderr);
		exit(1);
	}
#endif
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd == -1)
	{
		perror("create udp socket....\n");
	}
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(atoi(argv[2]));
	inet_aton(argv[1], &servaddr.sin_addr.s_addr);
	if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
	{
		printf("set ip address error!\n");
		exit(0);
	}
#if 1
	if(argv[3]!=NULL)
	{
		perror("bind");
		bzero(&clientaddr, sizeof(clientaddr));
		clientaddr.sin_family = AF_INET;
		clientaddr.sin_port = htons(atoi(argv[2]));
		inet_aton(argv[3], &clientaddr.sin_addr.s_addr);
		if(inet_pton(AF_INET, argv[3], &clientaddr.sin_addr) <= 0)
		{
			printf("set ip address error!\n");
			exit(0);
		}
	    if (bind(sockfd, (struct sockaddr *) &clientaddr, sizeof(struct sockaddr_in)) == -1)
	    {
	    	perror("udp bind......");
	    }
	}
#endif
	//inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr.s_addr);
	if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))==-1)
	{
		perror("udp connect....");
		exit(0);
	}
	return sockfd;
}


int main(int argc, char *argv[])
{
	int s_fd,len,count=0;
	char buf[MAX_LINE];
	char rcvbuf[MAX_LINE];
	memset(buf,0,MAX_LINE);
    s_fd = getUdpClietnSocketId(argc,argv);
     while(1)
     {
    	if(checkSelect(STDIN_FILENO,"r")==0)
    	{
    		memset(buf,0,MAX_LINE);
			#if 1
				   if(fgets(buf,MAX_LINE,stdin)!=NULL)
				   {
					   /*fgets()会在结尾将换行符'\n'读入到缓冲区,而gets()不会,因此需要将多余的\n去掉,更改为字符串结尾标识'\0'*/
						 buf[strlen(buf)-1]='\0';
			#endif
			#if 0
					 if(gets(buf)!=NULL)
					 {
			#endif

						 if((strlen(buf)==0)||(buf[0]=='\0'))
						 {  // printf("send len:%d : %s\n",strlen(buf),buf);
							 continue;
						 }
						 len = my_write(s_fd, buf, strlen(buf)); /* 发送字符串,该串包含‘\0’结束符 */
						 if(len == -1) /* 写操作失败,程序退出 */
						 {
							 perror("udp write....");
							 exit(1);
						 }
						 else
						 {
							 printf("send len:%d : %s\n",strlen(buf),buf);
						 }
				     }
    	 }
    		/* 读取服务器程序发回的串,由于是同一台主机通信,不存在延时的问题。
    		* 但是在真正的网络环境中,要处理读操作的延时问题。
    		*/
		if(checkSelect(s_fd,"r")==0)
		{
			memset(rcvbuf,0,sizeof(rcvbuf));
			while(1)
			{
				len = read(s_fd, rcvbuf, sizeof(rcvbuf));
				if(len>0)
				{
					printf("recV len;%d : %s\n",len, rcvbuf); /* 打印该串 */
				}
				if(len == -1) /* 读失败,退出程序 */
				{
					 exit(1);
				}
				break;
			}
		}
		//printf("-------------------\n");
    	syslog(LOG_USER|LOG_INFO,"count: %d",count++);
     }
 	if(close(s_fd) == -1)
 	{ /* 关闭套接字,结束通信 */
 		perror("fail to close");
 		exit(1);
 	}

 	return 0;
}

4:代码执行结果






其测试代码可以在:linux udp测试代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

家有工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值