一個多播例子的伺服器端與客戶端
阿新 • • 發佈:2019-01-30
下面是一個多播伺服器的例子。多播伺服器的程式設計很簡單,建立一個數據包套接字,選定多播的IP地址和埠,直接向此多播地址傳送資料就可以了。多播伺服器的程式設計,不需要伺服器加入多播組,可以直接向某個多播組傳送資料。
下面的例子持續向多播IP地址"224.0.0.88"的8888埠傳送資料"BROADCAST TEST DATA",每傳送一次間隔5s。
- /*
- *broadcast_server.c - 多播服務程式
- */
- #define MCAST_PORT 8888;
- #define MCAST_ADDR "224.0.0.88"//*一個區域性連線多播地址,路由器不進行轉發*/
- #define MCAST_DATA "BROADCAST TEST DATA" /*多播發送的資料*
- #define MCAST_INTERVAL 5 /*傳送間隔時間*/
- int main(int argc, char*argv)
- {
- int s;
- struct sockaddr_in mcast_addr;
- s = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字*/
- if (s == -1)
- {
- perror("socket()");
- return -1;
- }
- memset(&mcast_addr, 0, sizeof(mcast_addr));/*初始化IP多播地址為0*/
- mcast_addr.sin_family = AF_INET; /*設定協議族類行為AF*/
- mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);/*設定多播IP地址*/
- mcast_addr.sin_port = htons(MCAST_PORT); /*設定多播埠*/
- /*向多播地址傳送資料*/
- while(1) {
- int n = sendto(s, /*套接字描述符*/
- MCAST_DATA, /*資料*/
- sizeof(MCAST_DATA), /*長度*/
- 0,
- (struct sockaddr*)&mcast_addr,
- sizeof(mcast_addr)) ;
- if( n <0)
- {
- perror("sendto()");
- return -2;
- }
- sleep(MCAST_INTERVAL); /*等待一段時間*/
- }
- return 0;
- }
11.3.6 一個多播例子的客戶端
多播組的IP地址為224.0.0.88,埠為8888,當客戶端接收到多播的資料後將打印出來。
客戶端只有在加入多播組後才能接受多播組的資料,因此多播客戶端在接收多播組的資料之前需要先加入多播組,當接收完畢後要退出多播組。
- /*
- *broadcast_client.c - 多播的客戶端
- */
- #define MCAST_PORT 8888;
- #define MCAST_ADDR "224.0.0.88" /*一個區域性連線多播地址,路由器不進行轉發*/
- #define MCAST_INTERVAL 5 /*傳送間隔時間*/
- #define BUFF_SIZE 256 /*接收緩衝區大小*/
- int main(int argc, char*argv[])
- {
- int s; /*套接字檔案描述符*/
- struct sockaddr_in local_addr; /*本地地址*/
- int err = -1;
- s = socket(AF_INET, SOCK_DGRAM, 0);/*建立套接字*/
- if (s == -1)
- {
- perror("socket()");
- return -1;
- }
- /*初始化地址*/
- memset(&local_addr, 0, sizeof(local_addr));
- local_addr.sin_family = AF_INET;
- local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- local_addr.sin_port = htons(MCAST_PORT);
- /*繫結socket*/
- err = bind(s,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;
- if(err <0)
- {
- perror("bind()");
- return -2;
- }
- /*設定迴環許可*/
- int loop = 1;
- err = setsockopt(s,IPPROTO_IP, IP_MULTICAST_LOOP,&loop, sizeof(loop));
- if(err <0)
- {
- perror("setsockopt():IP_MULTICAST_LOOP");
- return -3;
- }
- struct ip_mreq mreq; /*加入廣播組*/
- mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*廣播地址*/
- mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*網路介面為預設*/
- /*將本機加入廣播組*/
- err = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof
- (mreq));
- if (err <0)
- {
- perror("setsockopt():IP_ADD_MEMBERSHIP");
- return -4;
- }
- int times = 0;
- int addr_len = 0;
- char buff[BUFF_SIZE];
- int n = 0;
- /*迴圈接收廣播組的訊息,5次後退出*/
- for(times = 0;times<5;times++)
- {
- addr_len = sizeof(local_addr);
- memset(buff, 0, BUFF_SIZE); /*清空接收緩衝區*/
- /*接收資料*/
- n = recvfrom(s, buff, BUFF_SIZE, 0,(struct sockaddr*)&local_addr,
- &addr_len);
- if( n== -1)
- {
- perror("recvfrom()");
- }
- /*列印資訊*/
- printf("Recv %dst message from server:%s\n", times, buff);
- sleep(MCAST_INTERVAL);
- }
- /*退出廣播組*/
- err = setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof
- (mreq));
- close(s);
- return 0;
- }