摘要
多播廣播是用於建立分步式系統:例如網絡游戲、ICQ聊天構建、遠程視頻會議系統的重要工具。使用多播廣播的程序和UDP向單個介紹方發送信息的程序相似。區別在於多播廣播程序使用特殊的多播IP地址。
目錄
一、配置Linux支持多播IP
二、使用Linux多播IP廣播數據
例如本地計算機的的IP地址是:127.0.0.1二它的多播地址是: 224.0.0.1。這是由RCF 1390定義的。為發送IP多播數據,發送者需要確定一個合適的多播地址,這個地址代表一個組。IPv4多播地址采用D類IP地址確定多播的組。在Internet中,多播地址范圍是從224.0.0.0到234.255.255.255。其中比較重要的地址有:
224.0.0.1 - 網段中所有支持多播的主機
224.0.0.2 - 網段中所有支持多播的路由器
224.0.0.4 - 網段中所有的DVMRP路由器
224.0.0.5 - 所有的OSPF路由器
224.0.0.6 - 所有的OSPF指派路由器
224.0.0.9 - 所有RIPv2路由器
IPv6地址空間中有1/256的地址空間分配給多播地址。一個FF(11111111)值標識該地址是多播地址。標識段高三位始終設置為0並保留。第四位T標識設置為0時表示一個永久分配的多播地址。T標識設置為1時,表示非永久分配的多播地址,這種地址作為一個臨時的多播地址。
一、配置Linux支持多播IP
在默認狀態下,大多Linux發行版本關閉的對多播IP的支持。為了在Linux系統使用多播套接口,需要從新配置和編譯Linux內核。下面看一下配置步驟:
1.cd /usr/src/linux
2.make menUConfig
3.選擇網絡選項
4.選中IP:Enable Multicasting IP一項
5.保存並從menuconfig 退出
6.運行:make dep;make clean;make bzlmage
7.cp/vmlinuz/vdimLz_good
8.cparch/i386/boot/zImage/vmlinzz
9.cd/etc
10.編輯lilo.conf,加入針對/vmlinuz_good的內核新選項
11.運行li1o
Linux內核編譯後,以超級用戶身份運行命令: #router add –net 224.0.0.0 netmask 224.0.0.0 dev lo
核實命令是否加入系統,運行命令:
#route –eKernel IP routing table
Destination gatewary Genmask Flags MSS Window irtt Iface
10.0.0.0 * 255.255.255.0 U 0 0 0 eth0
127.0.0.0 * 255.0.0.0 U 0 0 0 lo
BASE_ADDRESS>MC * 240.0.0.0 U 0 0 0 lo
Default 10.0.0.1 0.0.0.0 UG 0 0 0 eth0
其中出現多播地址: 224.0.0.1。就表示配置成功了。
二、使用Linux多播IP廣播數據
1、首先在服務器端建立多播程序:
服務器端程序代碼和解釋:
/* * broadcast.c - An IP multicast server */
#include
#include
#include
#include
#include #include
#include int port = 6789;
int main(void)
{
int socket_descriptor;
struct sockaddr_in address;
/* 首先建立套接口 */
socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_descriptor == -1)
{
perror("Opening socket");
exit(EXIT_FAILURE);
}
/* 初始化IP多播地址 */
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("224.0.0.1");
address.sin_port = htons(port);
/* 開始進行IP多播 */
while(1) {
if(sendto(socket_descriptor, "test from broadcast",
sizeof("test from broadcast"), 0,
(struct sockaddr *)&address, sizeof(address)) < 0)
{
perror("sendto");
exit(EXIT_FAILURE);
}
sleep(2);
}
exit(EXIT_SUCCESS);}
2、創建Linux客戶端的程序多播IP廣播
建立好廣播服務器後,就需要一個客戶端的收聽程序,收聽多播IP廣播要求在程序中作以下幾項工作:
(1)、多播方收聽,客戶端編寫通知Linux內核每個指定的套接口加入多播IP廣播組。
(2)、收聽方必須運行在同一個Linux計算機的不同進程的同一個套接口。
(3)、編寫配置端口設定廣播信息可以發送給同一個Linux主機,這樣作的用處是在同一個Linux主機上測試廣播程序和收聽程序,易於調試。
客戶端程序代碼和解釋:
/* * listen.c - An IP multicast client */
#include
#include
#include
#include
#include
#include
#include
char * host_name = "224.0.0.1";
/* 多播IP地址 */
int port = 6789;
int main(void)
{
struct ip_mreq command;
int loop = 1;
/* 多播循環 */
int iter = 0;
int sin_len;
char message[256];
int socket_descriptor;
struct sockaddr_in sin;
struct hostent *server_host_name;
if((server_host_name = gethostbyname(host_name)) == 0)
{
perror("gethostbyname");
exit(EXIT_FAILURE);
}
/*bzero(&sin, sizeof(sin));*/
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(port);
if((socket_descriptor = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
{ perror("socket");
exit(EXIT_FAILURE);
}
/* 調用bind之前,設置套接口選項啟用多播IP支持*/
loop = 1;
if(setsockopt(socket_descriptor,
SOL_SOCKET, SO_REUSEADDR,
&loop, sizeof(loop)) < 0)
{
perror("setsockopt:SO_REUSEADDR");
exit(EXIT_FAILURE);
}
if(bind(socket_descriptor,
(struct sockaddr *)&sin, sizeof(sin)) < 0)
{
perror("bind");
exit(EXIT_FAILURE);
}
/* 在同一個主機上進行廣播設置套接口,
作用是方便單個開發系統上測試多播IP廣播 */
loop = 1;
if(setsockopt(socket_descriptor,
IPPROTO_IP, IP_MULTICAST_LOOP,
&loop, sizeof(loop)) < 0)
{
perror("setsockopt:IP_MULTICAST_LOOP");
exit(EXIT_FAILURE);
}
/* 加入一個廣播組。進一步告訴Linux內核,
特定的套接口即將接受廣播數據*/
command.imr_multiaddr.s_addr = inet_addr("224.0.0.1");
command.imr_interface.s_addr = htonl(INADDR_ANY);
if(command.imr_multiaddr.s_addr == -1)
{
perror("224.0.0.1 not a legal multicast address");
exit(EXIT_FAILURE);
}
if (setsockopt(socket_descriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&command, sizeof(command)) < 0)
{
perror("setsockopt:IP_ADD_MEMBERSHIP");
}
while(iter++ < 8)
{
sin_len = sizeof(sin);
if(recvfrom(socket_descriptor, message, 256, 0,
(struct sockaddr *)&sin, &sin_len) == -1) {
perror("recvfrom");
}
printf("Response #%-2d from server: %s\n", iter, message);
sleep(2); }
/* 接受8個廣播後退出 */
if(setsockopt(socket_descriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
&command, sizeof(command)) < 0) {
perror("setsockopt:IP_DROP_MEMBERSHIP");
}
close(socket_descriptor);
exit(EXIT_SUCCESS);}
3、運行Linux多播IP程序
運行程序,打開兩個終端窗口並在每個窗口中輸入以上的源代碼。在一個窗口中鍵入make,編譯broadcast和1isten這兩個的可執行文件,由GUN make建立一個Makfiles文件。GUN make是Linux系統中一個自動生成和維護目標程序的工具。
在一個窗口中通過執行./broadcast,在另一個的窗口執行./listen,啟動收聽程序,你應該看到如下輸出:
#./listenResponse #1 form sever :test from broadcast
Response #2 form sever :test from broadcast
Response #3 form sever :test from broadcast
Response #4 form sever :test from broadcast
Response #5 form sever :test from broadcast
Response #6 form sever :test from broadcast
Response #7 form sever :test from broadcast
Response #8 form sever :test from broadcast
#
4、總結
Linux多播IP是一種同時向價格進程高效的發送信息的介紹。
多播傳輸中,數據被發送到接收者的多播地址,而不是每個接收者的單播地址,發送者只發送一個數據拷貝,源端到目標端路徑上的中間節點復制該數據。現在多播IP已經廣泛應用於網絡游戲、視頻廣播的領域。
4、總結
Linux多播IP是一種同時向價格進程高效的發送信息的介紹。多播傳輸中,數據被發送到接收者的多播地址,而不是每個接收者的單播地址,發送者只發送一個數據拷貝,源端到目標端路徑上的中間節點復制該數據。現在多播IP已經廣泛應用於網絡游戲、視頻廣播的領域。