组播

单播方式只能发给一个接收方
广播方式发给所有的主机。过度的广播会大量占用网络带宽,造成广播风暴,影响正常通信。

组播(又称为多播)是一种折中的方式。只有加入某个多跛足的主机才能收到数据。
多播方式既可以发给多个主机,又能避免像广播那样带来过多的负荷(每台主机要到传输层才能判断广播包是否要处理)

网络地址:

A类地址:

第1个字节为网络地址,其他3个字节为主机地址

第一个字节的最高位固定为0

地址范围 1.0.0.1 - 126.255.255.255

B类地址:
第一个和第二个字节为网络地址,其他2个字节为主机地址,第一个字节的前两位固定为10

地址范围:128.0.0.1 - 191.255.255.255

C类地址:

前3个字节为网络地址,最后1个字节是主机地址。第一字节的前3位固定为110

地址范围:192.0.0.1 - 223.255.255.255

D类地址:(组播地址)

不分网络地址和主机地址,第一个字节的前4位固定为1110

地址范围: 224.0.0.1 - 239.255.255.255

224.0.0.1 - 224.0.0.255是被保留的地址,组播的时候不要占用。

 

组播的发送;

创建数据报套接字

接收方地址指定为组播地址

指定端口信息

发送数据包


例如:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>

int main(int argc, char **argv)
{
int sockfd, clientfd;
struct sockaddr_in servaddr, clientaddr;
char buf[1024];
socklen_t len;
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket");
exit(1);
}

printf("socket = %d\n", sockfd);

memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);
servaddr.sin_addr.s_addr = inet_addr(argv[1]);


int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

len = sizeof(clientaddr);
while(1)
{
fgets(buf, sizeof(buf), stdin);
sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, len);
}
}

组播的接受

创建套接字
加入多播组
struct ip_mreq mreq;
bzero(&mreq, sizeof(mreq));
mreq.imr_multiaddr.s_addr = inet_addr("224.10.10.1");
mreq.imr_interface.s_addr = htonl(INADDR_ANY);

setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq));

绑定
等待接收

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <dirent.h>
#include <bits/time.h>

#define BUFSIZE 1024


int main()
{
int sockfd, clientfd;
struct sockaddr_in servaddr, clientaddr;
char buf[1024];
socklen_t len;

if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket");
exit(1);
}

struct ip_mreq mreq;
bzero(&mreq, sizeof(mreq));
mreq.imr_multiaddr.s_addr = inet_addr("224.10.10.1");
mreq.imr_interface.s_addr = htonl(INADDR_ANY);

setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq));


printf("socket = %d\n", sockfd);

memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);
//servaddr.sin_addr.s_addr = inet_addr("192.168.1.241");
servaddr.sin_addr.s_addr = INADDR_ANY;

if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
perror("bind");
exit(1);
}

while(1)
{
len = sizeof(clientaddr);
recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&clientaddr, &len);
printf("ip = %s, port = %d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
printf("buf = %s\n", buf);
}

return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2012-07-06 20:31  孟浩依然  阅读(269)  评论(0编辑  收藏  举报