现在的位置: 首页 > 综合 > 正文

Linux之广播和多播

2014年01月06日 ⁄ 综合 ⁄ 共 2790字 ⁄ 字号 评论关闭

最近学习Linux网络编程学到了广播与多播,就在这做点笔记。其中一些原理我就不介绍了,我觉得学习Linux网络编程,TCP/IP三卷还是基础,是需要好好看看。

广播的服务器端 :

#include <sys/socket.h>
//#include <sys/inet.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <time.h>

#define BUFLEN 255

void getcurtime(char *curtime)
{
	time_t tm = time(NULL);
	sprintf(curtime, "time : %d \n",tm);
}

int main(int argc, char **argv)
{
	struct sockaddr_in peeraddr ;
	int sockfd;
	int optval = 1;
	char msg[BUFLEN+1];	

	if( argc != 3 )
	{
		perror("can't input ADDRESS and PORT \n");
		_exit(1);
	}

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);              			    //设置套接字
	if( sockfd < 0 ) 
	{
		perror("socket fail \n");
		_exit(1);
	}

	setsockopt(sockfd, SOL_SOCKET,SO_BROADCAST,&optval, sizeof optval);         //设置广播方式,SO_BROADCAST
	memset(&peeraddr, 0, sizeof(struct sockaddr_in) );
	peeraddr.sin_family = AF_INET ;

	if( inet_aton(argv[1], &peeraddr.sin_addr) == 0 )
	{
		perror("inet_aton fail \n");
		_exit(1);
	}

	peeraddr.sin_port = htons(atoi(argv[2]) );
	printf("-------------广播服务器启动------------\n");
	while(1)
	{
		getcurtime(msg);
		sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&peeraddr, sizeof (struct sockaddr) );
		//printf("sendto return %d  \n",a);
		fflush(stdout);	
		sleep(3);
	}

	return 1;


}

下面是客户端 :

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#define BUFLEN 255

int main(int argc, char **argv)
{
	struct sockaddr_in localaddr;
	int sockfd,n;
	char msg[BUFLEN+1];

	if(argc != 2)
	{
		perror("port error \n");
		_exit(1);
	}

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if( sockfd < 0)
	{
		perror("sock fail \n");
		_exit(1);
	}
	
	localaddr.sin_port = htons(atoi(argv[1]) );
	localaddr.sin_addr.s_addr = htonl(INADDR_ANY);

	int optval = SO_REUSEADDR ;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval,sizeof optval);
	
	if(bind(sockfd, (struct sockaddr *)&localaddr, sizeof (struct sockaddr) ) < 0 )
	{
		perror("bind fail \n");
		_exit(1);
	}

	if( n = read(sockfd, msg,BUFLEN) == -1 )
	{
		perror("read error \n");
		_exit(1);
	}
	else
	{
		msg[n] = '0';
		printf("read time : %s \n",msg);
	}
	return 1;
}

下面是多播,服务器端不需要太大的变动,只需要将广播工作方式去掉,发送地址指定为多播地址即可。但客户端需要加入多播组,没有加入多播组的客户端接受到数据报后就会丢弃。

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#define BUFLEN 255

int main(int argc, char **argv)
{
	struct sockaddr_in localaddr;
	int sockfd,n;
	char msg[BUFLEN+1];
	struct ip_mreq mcaddr;          //D类多播地址结构体
	if(argc != 2)
	{
		perror("port error \n");
		_exit(1);
	}

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if( sockfd < 0)
	{
		perror("sock fail \n");
		_exit(1);
	}
	
	localaddr.sin_port = htons(atoi(argv[2]) );
	localaddr.sin_addr.s_addr = htonl(INADDR_ANY);

	//加入哪个多播组有命令行决定
	if( inet_aton(argv[1],&mcaddr.imr_mutiaddr) < 0 )             //D类多播IP地址
	{
		perror("null mcaddr \n");
		_exit(1);
	}

	printf("ip : %d \n",inet_ntoa(mcaddr.imr_multiaddr) );
	fflush(stdout);

	int optval = SO_REUSEADDR ;
	if( setsockopt(sockfd, IPPROTO_TP, IP_ADD_MEMBERSHIP, &mcaddr,sizeof (stuct ip_mreq)) < 0 )   //加入多播组
	{
		perror("join mcaddr fail \n");
		_exit(1);
	}
	
	if(bind(sockfd, (struct sockaddr *)&localaddr, sizeof (struct sockaddr) ) < 0 )
	{
		perror("bind fail \n");
		_exit(1);
	}

	if( n = read(sockfd, msg,BUFLEN) == -1 )
	{
		perror("read error \n");
		_exit(1);
	}
	else
	{
		msg[n] = '0';
		printf("read time : %s \n",msg);
	}
	return 1;
}

抱歉!评论已关闭.