zoukankan      html  css  js  c++  java
  • 组播

    组播

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

    组播(多播)为折中方式,只有加入某个多播组的主机才能收到数据。

    组播的IP地址:224.0.0.1 ~ 239.255.255.254(中间除去广播地址)


    组播的发送

    1)创建UDP套接字

    2)指定目标地址与端口

    3)发送数据包

     1 /*udp demo */
     2 
     3 /* usage:
     4  * ./client serv_ip serv_port 
     5 */
     6 #include "net.h"
     7 void usage (char *s)
     8 {
     9     printf ("
    This is multicast demo!
    ");
    10     printf ("
    Usage:
    	 %s serv_ip serv_port", s);
    11     printf ("
    	 serv_ip: udp server ip address(between 224~239 segment)");
    12     printf ("
    	 serv_port: udp server port(serv_port > 5000)
    
    ");
    13 }
    14 
    15 int main (int argc, char *argv[])
    16 {
    17     int fd = -1;
    18     int port = SERV_PORT;
    19 
    20     port = atoi (argv[2]);
    21     if (port < 0 || (port > 0 && port <= 5000)) {
    22         usage (argv[0]);
    23         exit (1);
    24     }
    25     struct sockaddr_in sin;
    26     if (argc != 3) {
    27         usage (argv[0]);
    28         exit (1);
    29     }
    30 
    31     /* 1. 创建socket fd */
    32     if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {    //UDP缂栫▼
    33         perror ("socket");
    34         exit (1);
    35     }
    36 
    37     /*2.1 填充struct sockaddr_in */
    38     bzero (&sin, sizeof (sin));
    39 
    40     sin.sin_family = AF_INET;
    41     sin.sin_port = htons (SERV_PORT);    //HBD转为NBD
    42 #if 0
    43     sin.sin_addr.s_addr = inet_addr (argv[1]);
    44 #else
    45     if (inet_pton (AF_INET, argv[1], (void *) &sin.sin_addr) != 1) {
    46         perror ("inet_pton");
    47         exit (1);
    48     }
    49 #endif
    50     printf ("multicast started!
    ");
    51     char buf[BUFSIZ];
    52     while (1) {
    53         fprintf (stderr, "pls input string:");
    54         bzero (buf, BUFSIZ);
    55         if (fgets (buf, BUFSIZ - 1, stdin) == NULL) {
    56             perror ("fgets");
    57             continue;
    58         }
    59 
    60         sendto (fd, buf, strlen (buf), 0, (struct sockaddr *) &sin, sizeof (sin));
    61 
    62         if (!strncasecmp (buf, QUIT_STR, strlen (QUIT_STR))) {    
    63             printf ("Client is exited!
    ");
    64             break;
    65         }
    66 
    67     }
    68     close (fd);
    69     return 0;
    70 }
    sender.c

    组播的接收

    1)创建UDP套接字

    2)加入多播组

    3)绑定地址与端口

    4)接收数据包

     1 #include "net.h"
     2 
     3 int main (void)
     4 {
     5 
     6     int fd = -1;
     7     struct sockaddr_in sin;
     8 
     9     /* 1. 创建socket fd */
    10     if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {    //udp
    11         perror ("socket");
    12         exit (1);
    13     }
    14 
    15     /* 2. 允许地址快速重用 */
    16     int b_reuse = 1;
    17     setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));
    18 
    19     /*加入多播组*/
    20     struct ip_mreq mreq;
    21     bzero(&mreq, sizeof(mreq)); //清零
    22     mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_IP);
    23     mreq.imr_interface.s_addr = htonl(INADDR_ANY);
    24     
    25     setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq));
    26 
    27     /*2. 绑定*/
    28     /*2.1 填充struct sockaddr_in */
    29     bzero (&sin, sizeof (sin));
    30     sin.sin_family = AF_INET;
    31     sin.sin_port = htons (SERV_PORT);    
    32     /* 使服务器可绑定在任意IP */
    33 #if 1
    34     sin.sin_addr.s_addr = htonl (INADDR_ANY);
    35 #else
    36     if (inet_pton (AF_INET, SERV_IP_ADDR, (void *) &sin.sin_addr) != 1) {
    37         perror ("inet_pton");
    38         exit (1);
    39     }
    40 #endif
    41     /*2.2 绑定 */
    42     if (bind (fd, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
    43         perror ("bind");
    44         exit (1);
    45     }
    46 
    47     char buf[BUFSIZ];
    48     struct sockaddr_in cin;
    49     socklen_t addrlen = sizeof (cin);
    50     printf ("
    multicast demo started!
    ");
    51     while (1) {
    52         bzero (buf, BUFSIZ);
    53         if (recvfrom (fd, buf, BUFSIZ - 1, 0, (struct sockaddr *) &cin, &addrlen) < 0) {
    54             perror ("recvfrom");
    55             continue;
    56         }
    57 
    58         char ipv4_addr[16];
    59         if (!inet_ntop (AF_INET, (void *) &cin.sin_addr, ipv4_addr, sizeof (cin))) {
    60             perror ("inet_ntop");
    61             exit (1);
    62         }
    63 
    64         printf ("Recived from(%s:%d), data:%s", ipv4_addr, ntohs (cin.sin_port), buf);
    65 
    66         if (!strncasecmp (buf, QUIT_STR, strlen (QUIT_STR))) {    /
    67             printf ("Client(%s:%d) is exiting!
    ", ipv4_addr, ntohs (cin.sin_port));
    68         }
    69 
    70     }
    71 
    72     close (fd);
    73 
    74     return 0;
    75 }
    recever.c
  • 相关阅读:
    字典树Trie
    转载一个不错的LRU cache
    git和github基础入门
    git基础之常用操作
    python矩阵和向量的转置问题
    梯度下降法注意要点
    python 浮点数问题
    Python数据分析基础——读写CSV文件2
    Python数据分析基础——读写CSV文件
    读书笔记----javascript函数编程
  • 原文地址:https://www.cnblogs.com/y4247464/p/12239414.html
Copyright © 2011-2022 走看看