多播
1.先來回顧一下,UDP廣播。一個服務器進行廣播,那么同一網(wǎng)絡的所有主機都會收到信息。那么這個時候,有可能并不是所有主機都需要收到廣播數(shù)據(jù)信息,只是一部分主機需要收到廣播數(shù)據(jù)信息而已。
2.UDP通信中的多播。多播是向特定組中的所有的主機發(fā)送數(shù)據(jù)的方法,多播也稱為組播。舉個容易理解的例子:我們在qq/wechat 中有10個聯(lián)系好友,拉了其中6個聯(lián)系好友建立了一個群。那么其他4個好友肯定收不到群里的消息。
3.多播數(shù)據(jù)傳輸?shù)奶攸c:
3.1 多播是向特定組中的所有主機傳輸數(shù)據(jù)的方法,多播也稱之為組播。
3.2 多播數(shù)據(jù)傳輸?shù)奶攸c。
a.多播發(fā)送者針對特定的多播組,只發(fā)送1次數(shù)據(jù),組內(nèi)主機均可收到數(shù)據(jù)
b.主機加入特定組,即可接收改組中的多播數(shù)據(jù)
c.多播組可在IP地址范圍內(nèi)任意增加
關鍵問題:如何收發(fā)多播數(shù)據(jù)?
1.多播組是一個D類地址(224.0.0.0 ~ 239.255.255.255)
2.加入多播組,可以理解為UDP網(wǎng)絡程序進行的申請(也就是申請D類地址)
2.1 如:申請接收發(fā)往 239.234.111.222 的多播數(shù)據(jù)
2.2 即:設置熟悉(IPPROTO_IP,IP_ADD_MEMBERSHIP)
3.發(fā)送多播數(shù)據(jù)的方式,與發(fā)送普通UDP數(shù)據(jù)的方式相同
3.1 預備操作:設置熟悉,如:(IPPROTO_IP,IP_MULTICAST_TTL)
注意事項
1.加入同一個多播組的主機不一定在同一個網(wǎng)絡中
2.因此,必須設置多播數(shù)據(jù)的最多轉(zhuǎn)發(fā)次數(shù)(TTL)
3.TTL (即:Time to Live) 是決定數(shù)據(jù)傳遞距離的注意因素
4.TTL 用整數(shù)表示,并且每經(jīng)過1個路由器就減少1
5.當TTL變?yōu)?時候,數(shù)據(jù)無法繼續(xù)傳遞,只能銷毀
多播程序設計:發(fā)送端
1.IP_MULTICAST_TTL :用于設置多播數(shù)據(jù)的 “最遠傳播距離”,默認:1
2.IP_MULTICAST_IF :用于設置多播數(shù)據(jù)從哪一個網(wǎng)絡接口(網(wǎng)卡)發(fā)送出去:默認:0.0.0.0 (也就是讓操作系統(tǒng)決定使用哪一個網(wǎng)口)
3.IP_MULTICAST_LOOP :用于設置多播數(shù)據(jù)是否發(fā)送會本機,默認:1
發(fā)送端:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int server = 0;
struct sockaddr_in saddr = {0};
int client = 0;
struct sockaddr_in remote = {0};
socklen_t asize = 0;
int len = 0;
char buf[32] = "Software";
int r = 0;
//int brd = 1;
server = socket(PF_INET, SOCK_DGRAM, 0);
if( server == -1 )
{
printf("server socket error\n");
return -1;
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY); // 本機地址
saddr.sin_port = htons(8888);
if( bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1 )
{
printf("udp server bind error\n");
return -1;
}
printf("udp server start success\n");
remote.sin_family = AF_INET;
remote.sin_addr.s_addr = inet_addr("224.1.1.168"); //設置一個多播地址
remote.sin_port = htons(9000);
// brd = 0;
//setsockopt(server, SOL_SOCKET, SO_BROADCAST, &brd, sizeof(brd));
while( 1 )
{
len = sizeof(remote);
r = strlen(buf);
sendto(server, buf, r, 0, (struct sockaddr*)&remote, len);
sleep(1);
}
close(server);
return 0;
}
接收端:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int sock = 0;
struct sockaddr_in addr = {0};
struct sockaddr_in remote = {0};
int len = 0;
char buf[128] = {0};
char input[32] = {0};
int r = 0;
//多播
struct ip_mreq group={0};
sock = socket(PF_INET, SOCK_DGRAM, 0);
if( sock == -1 )
{
printf("socket error\n");
return -1;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(9000);
if( bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1 )
{
printf("udp bind error\n");
return -1;
}
//remote.sin_family = AF_INET;
//remote.sin_addr.s_addr = inet_addr("127.0.0.1");
//remote.sin_port = htons(8888);
group.imr_multiaddr.s_addr=inet_addr("224.1.1.168");
group.imr_interface.s_addr=htonl(INADDR_ANY); //local host
//這里INADDR_ANY 為0.0.0.0 通過看ipconfig/ifconfig 可以看到有多個
//網(wǎng)絡ip地址,這個時候讓操作系統(tǒng)選擇哪一個端口進行多播數(shù)據(jù)收發(fā)。
//在實際的工程中需要明確指定需要哪一個網(wǎng)絡地址進行多播數(shù)據(jù)收發(fā),
//不能完全依賴操作系統(tǒng),否者有時候能夠收到數(shù)據(jù),有時候收不到數(shù)據(jù)。
setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,&group,sizeof(group));
while( 1 )
{
len=sizeof(remote);
r = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&remote, &len);
if( r > 0 )
{
buf[r] = 0;
printf("Receive: %s\n", buf);
}
else
{
break;
}
}
close(sock);
return 0;
}
運行結果:
發(fā)送端:
wj@ubuntu:~/DTSocket/17$ gcc mul_tx_server.c -o mul_tx_server.out
wj@ubuntu:~/DTSocket/17$ ./mul_tx_server.out
udp server start success
接收端:
wj@ubuntu:~/DTSocket/17$ gcc mul_rx_client.c -o mul_rx_client.out
wj@ubuntu:~/DTSocket/17$ ./mul_rx_client.out
Receive: Software
Receive: Software
Receive: Software
demo2:
//
//文章來源:http://www.zghlxwxcb.cn/news/detail-521832.html
小結:
1.單播:一對一數(shù)據(jù)發(fā)送,即:指定目標主機發(fā)送數(shù)據(jù)
2.廣播:
2.1 本地廣播:本地局域網(wǎng)廣播數(shù)據(jù),所有主機均可接收數(shù)據(jù)
2.2 直接廣播:直接網(wǎng)絡廣播數(shù)據(jù),目標網(wǎng)絡中的主機均可接收數(shù)據(jù)。
3.多播(組播) :向指定的多播地址發(fā)送數(shù)據(jù),“訂閱”該地址的主機均可接收數(shù)據(jù)。文章來源地址http://www.zghlxwxcb.cn/news/detail-521832.html
到了這里,關于UDP多播:一對多數(shù)據(jù)收發(fā)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!