最近学习Linux网络编程学到了广播与多播,就在这做点笔记。其中一些原理我就不介绍了,我觉得学习Linux网络编程,TCP/IP三卷还是基础,是需要好好看看。
广播的服务器端 :
#include
//#include
#include
#include
#include
#include
#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
#include
#include
#include
#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
#include
#include
#include
#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;
}