精华内容
参与话题
问答
  • 网络中存在往A、B所在的机器的8888端口发送单播UDP数据 A:端口复用绑定在端口8888上 B:端口复用绑定在端口8888上操作步骤:(1)先启动A(2)再启动B(3)B退出预期结果:(1)A 正常接收数据(2)B 正常接收数据,A收不到数据(3)...
    • UDP单播通信
    一、
    预置条件
    A、B在同一台机器,网络中存在往A、B所在的机器的8888端口发送单播UDP数据
    A:端口复用绑定在端口8888上
    B:端口复用绑定在端口8888上


    操作步骤:
    (1)先启动A
    (2)再启动B
    (3)B退出


    预期结果:
    (1)A 正常接收数据
    (2)B 正常接收数据,A收不到数据
    (3)A 正常接收数据

    二、
    预置条件
    A、B在同一台机器,网络中存在往A、B所在的机器的8888端口发送单播UDP数据
    A:绑定在端口8888上
    B:端口复用绑定在端口8888上


    操作步骤:
    (1)先启动A
    (2)再启动B
    (3)关闭A和B,先启动B再启动A


    预期结果:
    (1)A 正常接收数据
    (2)B 启动失败,绑定端口失败
    (3)B 启动正常,并正常接收数据,A绑定端口失败

    • 组播通信
    一、
    预置条件
    A、B在同一台机器,网络中存在往8888端口发送组播数据
    A:端口复用绑定在端口8888上,并加入组播组
    B:端口复用绑定在端口8888上,并加入组播组


    操作步骤:
    (1)先启动A
    (2)再启动B


    预期结果:
    (1)A 正常接收数据
    (2)A和B 正常接收数据

    二、
    预置条件
    A、B在同一台机器,网络中存在两个往8888端口发送组播数据,组播地址是:224.0.0.100和224.0.0.101
    A:端口复用绑定在端口8888上,并加入224.0.0.100组播组
    B:端口复用绑定在端口8888上,并加入224.0.0.101组播组


    操作步骤:
    (1)先启动A
    (2)再启动B


    预期结果:
    (1)A 接收到224.0.0.100组播组的组播数据,B收不到任何数据
    (2)A和B 接收到224.0.0.100和224.0.0.101组播组的组播数据

    三、
    预置条件
    A、B在同一台机器,网络中存在往8888端口发送组播数据
    A:绑定在端口8888上
    B:端口复用绑定在端口8888上


    操作步骤:
    (1)先启动A
    (2)再启动B
    (3)关闭A和B,先启动B再启动A


    预期结果:
    (1)A 正常接收数据
    (2)B 启动失败,绑定端口失败
    (3)B 启动正常,并正常接收数据,A绑定端口失败


    • 组播和UDP单播通信
    一、
    预置条件
    A、B、C、D在同一台机器,网络中存在往8888端口发送组播数据,同时存在往A、B、C、D所在的机器的8888端口发送单播UDP数据
    A: UDP单播 端口复用绑定在端口8888上
    C: 端口复用绑定在端口8888上,并加入组播组


    操作步骤:
    (1)先启动A
    (2)再启动C
    (3)C退出


    预期结果:
    (1)A 正常接收单播数据
    (2)C 正常接收组播以及单播数据,A只能收到组播数据
    (3)A 正常接收单播数据

    二、
    预置条件
    A、B、C、D在同一台机器,网络中存在往8888端口发送组播数据,同时存在往A、B、C、D所在的机器的8888端口发送单播UDP数据
    A: UDP单播 端口复用绑定在端口8888上
    C: 端口复用绑定在端口8888上,并加入组播组


    操作步骤:
    (1)先启动C
    (2)再启动A
    (3) 
    1.先退出C
    2.先退出A


    预期结果:
    (1)C 正常接收组播数据
    (2)A 正常接收组播以及单播数据,C正常收到组播数据
    (3)1. A正常接收单播数据  2.C 正常接收单播以及组播数据


    代码:
    组播multicast_recv.c:
    /*
     * *multicast_recv.c
     * */
    #include <sys/types.h>    
    #include <sys/socket.h>    
    #include <netinet/in.h>    
    #include <arpa/inet.h>    
    #include <time.h>    
    #include <string.h>    
    #include <stdio.h>    
    #include <unistd.h>    
    #include <stdlib.h>
    #define MCAST_PORT 8888
    #define MCAST_ADDR "224.0.0.100"     /*一个局部连接多播地址,路由器不进行转发*/
    #define LOCAL_ADDR "192.168.50.21"     /*本机网卡地址*/
    #define MCAST_INTERVAL 5             /*发送间隔时间*/
    #define BUFF_SIZE 256                /*接收缓冲区大小*/
    int main(int argc, char*argv[])
    {  
        struct sockaddr_in local_addr;              /*本地地址*/
       
        int fd = socket(AF_INET, SOCK_DGRAM, 0);     /*建立套接字*/
        if (fd == -1)
        {
            perror("socket()");
            exit(1);
        }  
    	
        int yes = 1;
        if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0)     
        {    
            perror("Reusing ADDR failed");    
            exit(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*/
        int err = bind(fd,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;
        if(err < 0)
        {
            perror("bind()");
            exit(1);
        }
       
        /*设置回环许可*/
        int loop = 1;
        err = setsockopt(fd,IPPROTO_IP, IP_MULTICAST_LOOP,&loop, sizeof(loop));
        if(err < 0)
        {
            perror("setsockopt():IP_MULTICAST_LOOP");
            exit(1);
        }
       
        /*加入多播组*/
        struct ip_mreq mreq;                                    
        mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*多播地址*/
        mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*本地网络接口为默认*/
    	
        /*将本机加入多播组*/
        err = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq));
        if (err < 0)
        {
            perror("setsockopt():IP_ADD_MEMBERSHIP");
            exit(1);
        }
       
        int times = 0;
        int addr_len = sizeof(local_addr);
        char buff[BUFF_SIZE];
        int n = 0;
    	
        /*循环接收多播组的消息,5次后退出*/
        while(1)
        {
            memset(buff, 0, BUFF_SIZE);                 /*清空接收缓冲区*/
    		
            /*接收数据*/
            n = recvfrom(fd, 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);
        }
       
        /*退出多播组*/
        err = setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof(mreq));
           
        close(fd);
        return 0;
    }

    组播multicast_send.c:
    /*
     * *broadcast_server.c - 多播服务程序
     * */
    #include <sys/types.h>    
    #include <sys/socket.h>    
    #include <netinet/in.h>    
    #include <arpa/inet.h>    
    #include <time.h>    
    #include <string.h>    
    #include <stdio.h>    
    #include <unistd.h>    
    #include <stdlib.h>
    #define MCAST_PORT 8888
    #define MCAST_ADDR "224.0.0.100"    /*一个局部连接多播地址,路由器不进行转发*/
    #define MCAST_DATA "BROADCAST TEST DATA"            /*多播发送的数据*/
    #define MCAST_INTERVAL 1                            /*发送间隔时间*/
    int main(int argc, char*argv)
    {
        struct sockaddr_in mcast_addr;     
        int fd = socket(AF_INET, SOCK_DGRAM, 0);         /*建立套接字*/
        if (fd == -1)
        {
            perror("socket()");
            exit(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(fd,MCAST_DATA,sizeof(MCAST_DATA),0,(struct sockaddr*)&mcast_addr,sizeof(mcast_addr)) ;
            if( n < 0)
            {
                perror("sendto()");
                exit(1);
            }      
            sleep(MCAST_INTERVAL);                          /*等待一段时间*/
        }
       
        return 0;
    }


    单播udp_recv.c:
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<errno.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<string.h>
    #define MCAST_PORT 8888
    #define LOCAL_ADDR "192.168.50.21"     /*本机网卡地址*/
    
    #define ERR_EXIT(m) \
        do { \
            perror(m); \
            exit(EXIT_FAILURE); \
        } while (0)
    
    	
    void echo_ser(int sock)
    {
        char recvbuf[1024] = {0};
        struct sockaddr_in peeraddr;
        socklen_t peerlen;
    	int i = 0;
    
        while (1)
        {
    
            peerlen = sizeof(peeraddr);
            memset(recvbuf, 0, sizeof(recvbuf));
            int n = recvfrom(sock, recvbuf, sizeof(recvbuf), 0,
                         (struct sockaddr *)&peeraddr, &peerlen);
            if (n == -1)
            {
                if (errno == EINTR)
                    continue;
    
                ERR_EXIT("recvfrom error");
            }
            else if(n > 0)
            {
                printf("==>(%d)-%s\n",++i,recvbuf);
            }
        }
        close(sock);
    }
    
    int main(void)
    {
        int sock;
        if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
            ERR_EXIT("socket error");
    
        struct sockaddr_in servaddr;
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(MCAST_PORT);
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        
        int yes = 1;
        if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0)
        {
            perror("Reusing ADDR failed");
            exit(1);
        }
    
        if (bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
            ERR_EXIT("bind error");
    
        echo_ser(sock);
    
        return 0;
    }

    单播udp_send.c:
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #define MCAST_PORT 8888
    #define LOCAL_ADDR "192.168.50.21"     /*本机网卡地址*/
    #define UDP_DATA "UDP TEST DATA"            /*UDP发送的数据*/
    #define UDP_INTERVAL 1                            /*发送间隔时间*/
    
    #define ERR_EXIT(m) \
            do \
            { \
                    perror(m); \
                    exit(EXIT_FAILURE); \
            } while(0)
    
    void echo_cli(int sock)
    {
        struct sockaddr_in servaddr;
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(MCAST_PORT);
        servaddr.sin_addr.s_addr = inet_addr(LOCAL_ADDR);
    	
        while (1)
        {
            int ret = sendto(sock, UDP_DATA, strlen(UDP_DATA), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
            if( ret < 0)
            {
                perror("sendto()");
                exit(1);
            }
            sleep(UDP_INTERVAL);                          /*等待一段时间*/
        }
    
        close(sock);
    }
    
    int main(void)
    {
        int sock;
        if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
            ERR_EXIT("socket");
    
        echo_cli(sock);
    
        return 0;
    }



    结论:
    1、UDP单播或者组播端口复用,想要成功,必须第一次创建socket的时候也要设置端口复用,第二次复用才能成功。
    2、UDP单播使用端口复用,会导致UDP数据总是被第二次启动的socket接收到,第一次启动的socket总是接收到,除非第二次启动的socke退出。
    3、两个组播接收者在同一个端口使用端口复用,都能接收到组播数据。
    4、UDP单播先启动,组播使用端口复用后启动,将导致UDP单播和组播数据都被后启动的接收者收到,而先启动的UDP单播接收者收不到以前的单播数据,反而能够收到组播数据。
    5、两个socket绑定在同一个端口,加入不同的组播组,最终导致两个socket能够收到两个不同组播组发送的数据。
    展开全文
  • 录制UDP组播数据到文件(1)

    千次阅读 2013-05-09 15:03:19
    网上的通常的UDP组播程序都只是简单的示例,通常也只是支持本机为网卡的情况, 未达到应用的级别。 本程序支持本机多网卡(即多IP),指定IP接收UDP组播数据存储成文件。 而且本程序是多线程并行的工作方式,能保证...
    简介:
    网上的通常的UDP组播程序都只是简单的示例,通常也只是支持本机为单网卡的情况,
    未达到应用的级别。
    本程序支持本机多网卡(即多IP),指定IP接收UDP组播数据存储成文件。
    而且本程序是多线程并行的工作方式,能保证数据并行接收与存储,从而不会造成数据丢失。
    本程序还对UDP组播数据的初始化,接收和结束进行了封装,方便应用开发。
    最后说明一下,本程序借鉴ffmpeg的相关代码,完全达到了应用开发级别,
    且可以用来理解ffmpeg对UDP数据的处理。

    ​完整的代码开以在这里下载:
    http://download.csdn.net/detail/fireroll/5348914

    一、main.c程序
    /******************************************************************************
     * \File
     *   main.c
     * \Brief
     *   Recording udp-multicast data into a file
     * \Author
     *   Hank
     * \Created date
     *   2013-03-12
     ******************************************************************************
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <getopt.h>


    #include "udp.h"


    #include <signal.h>
    #include <limits.h>
    #include <unistd.h>


    /* 
     * 和键盘命令响应相关 
     * 可以参见我的另一篇文章:
     * http://blog.chinaunix.net/uid-26000296-id-3429028.html
     */
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <sys/time.h>
    #include <termios.h>


    static struct termios oldtty;
    static int q_pressed = 0;
    static int verbose = 1;
    static int using_stdin = 0;
    static int run_as_daemon = 0;


    static volatile int received_sigterm = 0;


    static void term_init(void);
    static void term_exit(void);
    static void sigterm_handler(int sig);
    static int read_key(void);




    extern char *optarg;
    extern int opterr;
    struct option opts[] = {
      {"addr", required_argument, NULL, 'i'},
      {"port", required_argument, NULL, 'p'},
      {"host", required_argument, NULL, 's'},
      {"out" , required_argument, NULL, 'o'},
      {"help", required_argument, NULL, 'h'},
      {0,0,0,0}
    };


    int parse_params(int argc, char** argv, char* host, char* addr, int* port,  char* f);


    int main(int argc, char* argv[])
    {
      char udp_addr[32]  = "225.1.1.31";
      int  udp_port      = 1234;
      char localhost[32] = "192.168.1.73";
      char filename[512] = "udp.dat";
      
      FILE *fp = NULL;
      int ret;
      int size, sum = 0;


      UDPContext *p_udpctx = NULL;


      char read_buf[4096];
      int key;


      /*Parsing command-line parameters */
      parse_params(argc, argv, localhost, udp_addr, &udp_port, filename);
      fp = fopen(filename, "wb");
      if (fp == NULL)
      {
        printf("Cann't open the file %s\n",filename);
        exit(1);
      }


      /* 处理键盘命令 */
      if (!using_stdin)
      {
        if (verbose >= 0)
          printf("Perss [q] to stop, [?] for help\n");
      }
      term_init();


      /* 初始化UDP组播数据录制 */
      ret = init_udp(&p_udpctx, localhost, udp_addr, udp_port); 


      for(; received_sigterm == 0;)
      {
        float cnt;
        /* if 'q' pressed, exits */
        if (!using_stdin)
        {
          if (q_pressed)
          break;


          /* read_key() returns 0 on EOF */
          key = read_key();
          if (key == 'q')
          {
            printf("quit\n");
            break;
          }
          if (key == '+') 
          {
            verbose++;
            printf("verbose = %d\n", verbose);
          }
          if (key == '-')
          { 
            verbose--;
            printf("verbose = %d\n", verbose);
          }
          if (key == '?')
          {
            printf("key function\n" 
                  "? show this help\n" 
                  "+ increase verbosity\n" 
                  "- decrease verbosity\n" 
                  "q quit\n"
                  );
          }
        }
        
        /* 将UDP组播数据取出并写到文件 */
        size = read_udp(p_udpctx, read_buf, 4096);
        fwrite(read_buf, size, 1, fp);
        memset(read_buf, 0, sizeof(read_buf));
        sum += size;
        cnt = (float)(sum/1024);


        printf("\rREC: read %d bytes, and write %f kBytes to file.", 
              size, cnt);
        fflush(stdout);
      }


      /* 结束UDP组播数据录制,并回收资源 */
      close_udp(&p_udpctx, localhost);
      fclose(fp);
      
      return 0;
    }






    int parse_params(int argc, char** argv, 
          char* host, char* addr, int* port,  char* f)
    {
      int c, index;


      opterr = 0;
      while ((c = getopt_long(argc, argv, "i:p:s:o:h", opts, NULL)) != -1)
      {
        switch (c)
        {
          case 'i':
            strcpy(addr, optarg);
            break;
          case 'p':
            *port = atoi(optarg);
            break;
          case 's':
            strcpy(host, optarg);
            break;
          case 'o':
            strcpy(f, optarg);
            break;
          case 'h':
          default:
            printf("Usage: \n");
            printf("-i addr : set udp-multicast's ip address\n");
            printf("-p port : set udp-multicast's port\n");
            printf("-s host : set local addresss\n");
            printf("-o file : set output filename\n");
            printf("-h      : print help information\n");
            exit (1);
        }
      }


      /* show banner */
      printf("addr : %s \nport : %d \nhost : %s \nfile : %s\n",
            addr, *port, host, f);


      for (index = optind; index < argc; index++)
      printf("Non-option argument %s\n", argv[index]);


      return 0;
    }




    static void term_init(void)
    {
      if (!run_as_daemon)
      {
        struct termios tty;


        tcgetattr(0, &tty);
        oldtty = tty;
        atexit(term_exit);


        tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
              |INLCR|IGNCR|ICRNL|IXON);
        tty.c_oflag |= OPOST;
        tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
        tty.c_cflag &= ~(CSIZE|PARENB);
        tty.c_cflag |= CS8;
        tty.c_cc[VMIN] = 1;
        tty.c_cc[VTIME] = 0;


        tcsetattr (0, TCSANOW, &tty);


        /* Quit (POSIX). */
        signal(SIGQUIT, sigterm_handler); 
      }


      signal(SIGINT , sigterm_handler);
      signal(SIGTERM, sigterm_handler); 
    }




    static void term_exit(void)
    {
      printf("%s\n", "TERMINATION");


      if (!run_as_daemon)
      tcsetattr(0, TCSANOW, &oldtty);
      exit(1);
    }


    static void sigterm_handler(int sig)
    {
      received_sigterm = sig;
      q_pressed++;
      term_exit();
    }


    /* 
     * \Func
     * read_key
     * \Descript
     * read a key without blocking
     */
    static int read_key(void)
    {
      int n = 1;
      unsigned char ch;
      struct timeval tv;
      fd_set rfds;


      if (run_as_daemon)
      return -1;


      FD_ZERO(&rfds);
      FD_SET(0, &rfds);


      tv.tv_sec = 0;
      tv.tv_usec = 0;
      n = select(1, &rfds, NULL, NULL, &tv);


      if (n > 0)
      {
        n = read(0, &ch, 1);


        if (n == 1)
        return ch;


        return n;
      }


      return -1;
    }


    二、udp.h头文件
    /******************************************************************************
     * \File
     *   udp.h
     * \Brief
     *    
     * \Author
     *   Hank
     * \Created date
     *   2013-03-13
     ******************************************************************************
     */
    #ifndef __UDP_H__
    #define __UDP_H__
    #include <stdint.h>
    #include <sys/socket.h>


    #define MAX_MALLOC_SIZE INT_MAX
    #define ALIGN 32


    #define UDP_MAX_PKT_SIZE 65536
    #define UDP_TX_BUF_SIZE  32768


    #define SUCCEED 0
    #define FAILED  1


    /* 
     * 使用环形FIFO的数据结构存储UDP组播数据 
     * 
     *          ____________________________________
     * buffer->|____________________________________|<-ptr_tail
     *            |                      |           
     *   ptr_read&idx_read        ptr_write/idx_write 
     */
    typedef struct UDPFifoBuf {
      uint8_t *buffer, *ptr_tail;     
      uint8_t *ptr_read, *ptr_write;
      uint32_t idx_read, idx_write;
    } UDPFifoBuf;


    /* UDP上下文数据结构 */
    typedef struct UDPContext {
      char addr[32];  // udp-multicast's address
      int  port;      // udp-multicast's port
      char host[32];  // localhost


      int  fd;  
      int  ttl;
      int  pkt_buf_size;
      int  reuse_socket;
      int  is_udp_multicast;


      struct sockaddr_storage udp_addr;
      int    udp_addr_len;


      struct sockaddr_storage my_addr;
      int    my_addr_len;


      UDPFifoBuf   *p_fifo;
      int  cir_buf_size;
      int  cir_buf_err;




      /* Have pthreads*/
      pthread_t thread_cir_buf;   //线程ID


    } UDPContext;


    int init_udp(UDPContext **pp_udpctx, char *host, char *addr, int port);
    int read_udp(UDPContext *p_ctx, char *p_buf, int size);
    int close_udp(UDPContext **pp_ctx, char *host);
    #endif


    三、udp.c程序
    /*!
     ******************************************************************************
     * \File
     *   udp.c
     * \Descipt
     *   
     * \Author
     *   Hank
     * \Created date
     *   2013-05-04
     ******************************************************************************
     */
    3.1. 头文件与宏定义
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <memory.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <pthread.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <arpa/inet.h>


    #include "udp.h"


    extern int errno;
    #ifndef IN_MULTICAST
    #define IN_MULTICAST(a) ((((uint32_t)(a)) & 0xf0000000) == 0xe0000000)
    #endif


    #define MAX_CIR_BUF_SIZE (7*188*4096)
    #define UDPMIN(a, b) ((a) > (b) ? (b) : (a))


    #define AVERROR(e) (-(e))   // Returns a negative error code from a POSIX error code,
                                // to return from library functions.
    #define udp_neterrno() AVERROR(errno)
    展开全文
  • UDP单播 组播 广播 区别及简单实现

    千次阅读 2020-04-22 16:40:20
    udp单播单播只能是发送方往接收方指定的IP 端口发送数据 组播需具备的条件 1、接收方设置组播属性及组播号 2、发送方往接收方定义的组播地址发送 3、服务器客户端端口号需要一致 广播需具备的条件 1、接收方...

    无论是tcp还是udp 服务器都必须绑定prot、Ip,客户端可以有选择性。

    udp单播: 单播只能是发送方往接收方指定的IP 端口发送数据

    组播需具备的条件  1、接收方设置组播属性及组播号  2、发送方往接收方定义的组播地址发送  3、服务器客户端端口号需要一致

    广播需具备的条件 1、接收方设置广播属性  2、发送方往接收方定义的组播地址发送  3、服务器客户端端口号需要一致


    组播和单播的区别:组播可以多设置一个IP(这里称为为组播地址224打头的),发送方除了可以往接收方绑定的IP发送,也可以                                                                                                                                                             往接收方设置的组播ip发送数据。
    组播和广播的区别:广播需要设置启动接收广播属性,发送方除了可以往接收方绑定的IP发送,也可以往255同网段IP发送。

    这三种udp模型  客户端的实现没有区别,区别仅仅在于发送的网络IP不一样

     

    广播是不会被路由器转发的,特点局域网通信,局域网游戏,客户端的统计 局域网群发等。

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

      udp unicast server code

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    /*udp和tcp客户端其实都可以绑定自身的IP端口也可以不绑定,
    不绑定的话系统会为你默认分配,而服务器则必须绑定端口 IP*/

    #include <Winsock2.h>
    #include <iostream>
    #include <thread>

    #pragma comment(lib, "Ws2_32.lib")

    using namespace std;

    int main(void)
    {
        /* 初始化winsock2库 */
        //Step 0. Initialize winsock2 library...
        WSADATA wsaData;

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        {
            return 1;
        }

        // Step 1. Ask system for a socket.this socket is waiter
        SOCKET sockServer = ::socket(PF_INET, SOCK_DGRAM, 0);

        if (sockServer == INVALID_SOCKET)
        {
            return 1;
        }

        //Step 2. bind the socket to a local address and port.接待套接字
        sockaddr_in addrServer = { 0 };
        addrServer.sin_family = AF_INET;
        addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
        addrServer.sin_port = 30001;
        if (::bind(sockServer, reinterpret_cast<const sockaddr*>(&addrServer),
            sizeof addrServer) == SOCKET_ERROR)
        {
            return 1;
        }

        char buf[100] = { 0 };
        sockaddr_in addrClient;
        int iSize = sizeof(addrClient);

       //recvfrom是阻塞的

        int iResult = recvfrom(sockServer, buf, 100, 0, reinterpret_cast<sockaddr*>(&addrClient), &iSize);

        closesocket(sockServer);
        WSACleanup();
        return 0;
    }

     

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

      udp unicast Client code

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    #include <Winsock2.h>
    #include <iostream>
    #include <thread>

    #pragma comment(lib, "Ws2_32.lib")

    using namespace std;

    int main(void)
    {
        /* 初始化winsock2库 */
        //Step 0. Initialize winsock2 library...
        WSADATA wsaData;

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        {
            return 1;
        }

        // Step 1. Ask system for a socket.this socket is waiter
        SOCKET sock2Server = ::socket(PF_INET, SOCK_DGRAM, 0);

        if (sock2Server == INVALID_SOCKET)
        {
            return 1;
        }

        //绑定自己的port  客户端也可以绑定自己的port ip 指定数据从什么端口出去
        //sockaddr_in addrBind = { 0 };
        //addrBind.sin_family = AF_INET;
        //addrBind.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
        //addrBind.sin_port = 30002;
        //if (::bind(sock2Server, reinterpret_cast<const sockaddr*>(&addrBind),
        //    sizeof addrBind) == SOCKET_ERROR)
        //{
        //    return 1;
        //}

        //设置接收方的port ip 下面的端口 ip需要和服务器一致
        sockaddr_in addrServer = { 0 };
        addrServer.sin_family = AF_INET;
        addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
        addrServer.sin_port = 30001;

        sendto(sock2Server, "hello", 6, 0, reinterpret_cast<sockaddr*>(&addrServer), sizeof(addrServer));

        closesocket(sock2Server);
        WSACleanup();
        return 0;
    }

     

     

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

      udp muticast server code

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    #include <Winsock2.h>
    #include <iostream>
    #include <thread>
    #include<Ws2tcpip.h>   //需要加上此头文件
    #pragma comment(lib, "Ws2_32.lib")

    using namespace std;

    int main(void)
    {
        /* 初始化winsock2库 */
        //Step 0. Initialize winsock2 library...
        WSADATA wsaData;

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        {
            return 1;
        }

        // Step 1. Ask system for a socket.this socket is waiter
        SOCKET sockServer = ::socket(PF_INET, SOCK_DGRAM, 0);

        if (sockServer == INVALID_SOCKET)
        {
            return 1;
        }

        //Step 2. bind the socket to a local address and port.接待套接字
        sockaddr_in addrServer = { 0 };
        addrServer.sin_family = AF_INET;
        addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
        addrServer.sin_port = 30001;
        if (::bind(sockServer, reinterpret_cast<const sockaddr*>(&addrServer),
            sizeof addrServer) == SOCKET_ERROR)
        {
            return 1;
        }

        //设置接收组播属性 

        ip_mreq mrq;
        mrq.imr_multiaddr.S_un.S_addr = inet_addr("224.0.0.11");//设置组播地址 满足前面是224即可224.0.0.1不能用
        mrq.imr_interface.S_un.S_addr = 0;   //设置自动选择网卡上面接收组播

        if (setsockopt(sockServer, IPPROTO_IP, IP_ADD_MEMBERSHIP, reinterpret_cast<const char*>(&mrq), sizeof(mrq))                 ==    SOCKET_ERROR)
        {
            return 1;
        }


        char buf[100] = { 0 };
        sockaddr_in addrClient;
        int iSize = sizeof(addrClient);

        int iResult = recvfrom(sockServer, buf, 100, 0, reinterpret_cast<sockaddr*>(&addrClient), &iSize);

        closesocket(sockServer);
        WSACleanup();
        return 0;
    }

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

      udp muticast client code

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    #include <Winsock2.h>
    #include <iostream>
    #include <thread>

    #pragma comment(lib, "Ws2_32.lib")

    using namespace std;

    int main(void)
    {
        /* 初始化winsock2库 */
        //Step 0. Initialize winsock2 library...
        WSADATA wsaData;

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        {
            return 1;
        }


        SOCKET sock2Server = ::socket(PF_INET, SOCK_DGRAM, 0);

        if (sock2Server == INVALID_SOCKET)
        {
            return 1;
        }

     
        //设置接收方的port ip 下面的端口
        sockaddr_in addrServer = { 0 };
        addrServer.sin_family = AF_INET;
        //点对点的也可以
        //addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
        //往服务器组播地址发也可以,相比单播多一个选择性 
        addrServer.sin_addr.S_un.S_addr = inet_addr("224.0.0.11");
        addrServer.sin_port = 30001;

        sendto(sock2Server, "hello", 6, 0, reinterpret_cast<sockaddr*>(&addrServer), sizeof(addrServer));

        closesocket(sock2Server);
        WSACleanup();
        return 0;
    }

     

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

      udp broadcast server code

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------


    //具备广播的条件  1、接收方设置广播属性 2、发送方往同网段的255IP地址发送 3、服务器客户端端口号需要一致
    #include <Winsock2.h>
    #include <iostream>
    #include <thread>

    #pragma comment(lib, "Ws2_32.lib")

    using namespace std;

    int main(void)
    {
        /* 初始化winsock2库 */
        //Step 0. Initialize winsock2 library...
        WSADATA wsaData;

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        {
            return 1;
        }

        // Step 1. Ask system for a socket.this socket is waiter
        SOCKET sockServer = ::socket(PF_INET, SOCK_DGRAM, 0);

        if (sockServer == INVALID_SOCKET)
        {
            return 1;
        }

        //Step 2. bind the socket to a local address and port.接待套接字
        sockaddr_in addrServer = { 0 };
        addrServer.sin_family = AF_INET;
        addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
        addrServer.sin_port = 30001;
        if (::bind(sockServer, reinterpret_cast<const sockaddr*>(&addrServer),
            sizeof addrServer) == SOCKET_ERROR)
        {
            return 1;
        }

        //设置接收广播属性 要设置了广播属性才可以接收广播消息   
        bool bEnableBroadcast = true;
        if (setsockopt(sockServer, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<const char*>(&bEnableBroadcast),                                               sizeof(bEnableBroadcast)) == SOCKET_ERROR)
        {
            return 1;
        }

        

        char buf[100] = { 0 };
        sockaddr_in addrClient;
        int iSize = sizeof(addrClient);

        int iResult = recvfrom(sockServer, buf, 100, 0, reinterpret_cast<sockaddr*>(&addrClient), &iSize);

        closesocket(sockServer);
        WSACleanup();
        return 0;
    }

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

      udp broadcast client code

    /------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    #include <Winsock2.h>
    #include <iostream>
    #include <thread>

    #pragma comment(lib, "Ws2_32.lib")

    using namespace std;

    int main(void)
    {
        /* 初始化winsock2库 */
        //Step 0. Initialize winsock2 library...
        WSADATA wsaData;

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        {
            return 1;
        }

        // Step 1. Ask system for a socket.this socket is waiter
        SOCKET sock2Server = ::socket(PF_INET, SOCK_DGRAM, 0);

        if (sock2Server == INVALID_SOCKET)
        {
            return 1;
        }

        //广播中服务器设置了广播属性的话 下
        //设置接收方的port ip 下面的端口
        sockaddr_in addrServer = { 0 };
        addrServer.sin_family = AF_INET;
        //点对点的也可以
        //addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
        //往255这个网段发的话 只要是设置了广播属性的服务器都可以接收到数据 
        addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.255");
        addrServer.sin_port = 30001;

        sendto(sock2Server, "hello", 6, 0, reinterpret_cast<sockaddr*>(&addrServer), sizeof(addrServer));

        closesocket(sock2Server);
        WSACleanup();
        return 0;
    }

     

    展开全文
  • udp组播demo

    2020-07-16 17:14:40
    udp组播 组播报文的目的地址使用D类IP地址, D类地址不能出现在IP报文的源IP地址字段。单播数据传输过程中,一个数据包传输的路径是从源地址路由到目的地址,利用“逐跳”的原理[路由选择]在IP网络中传输。 然而在ip...

    udp组播

    组播报文的目的地址使用D类IP地址, D类地址不能出现在IP报文的源IP地址字段。单播数据传输过程中,一个数据包传输的路径是从源地址路由到目的地址,利用“逐跳”的原理[路由选择]在IP网络中传输。

    然而在ip组播环中,数据包的目的地址不是一个,而是一组,形成组地址。所有的信息接收者都加入到一个组内,并且一旦加入之后,流向组地址的数据立即开始向接收者传输,组中的所有成员都能接收到数据包。组播组中的成员是动态的,主机可以在任何时刻加入和离开组播组。

    用同一个IP多播地址接收多播数据包的所有主机构成了一个主机组,也称为多播组。一个多播组的成员是随时变动的,一台主机可以随时加入或离开多播组,多播组成员的数目和所在的地理位置也不受限制,一台主机也可以属于几个多播组。此外,不属于某一个多播组的主机也可以向该多播组发送数据包。

    组播地址

    组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。
    224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
    224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;
    224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
    239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。
    组播是一对多的传输方式,其中有个组播组的 概念,发送端将数据向一个组内发送,网络中的路由器通过底层的IGMP协议自动将数据发送到所有监听这个组的终端。至于广播则和组播有一些相似,区别是路由器向子网内的每一个终端都投递一份数据包,不论这些终端是否乐于接收该数据包。UDP广播只能在内网(同一网段)有效,而组播可以较好实现跨网段群发数据。

    UDP组播是采用的无连接,数据报的连接方式,所以是不可靠的。也就是数据能不能到达接受端和数据到达的顺序都是不能保证的。但是由于UDP不用保证数据 的可靠性,所有数据的传送效率是很快的。

    组播的原理

    组播首先由一个用户申请一个组播组,这个组播组被维护在路由器中,其他用户申请加入组播组,这样当一个用户向组内发送消息时,路由器将消息转发给组内的所有成员。如果申请加入的组不在本级路由中,如果路由器和交换机允许组播协议通过,路由器将申请加入的操作向上级路由提交。广域网通信要经过多级路由器和交换机,几乎所有的网络设备都默认阻止组播协议通过(只允许本网段内,不向上级提交),这使得广域网上实现组播有一定局限。

    UDP组播的基本步骤

    建立socket
    socket和端口绑定
    加入一个组播组
    通过sendto / recvfrom进行数据的收发
    关闭socket

    如何加入一个组
    struct ip_mreq mreq;
    
    mreq.imr_multiaddr.s_addr  组播IP地址  230.1.1.1
    mreq.imr_interface.s_addr  IP地址      监听IP地址  
    

    udp组播接收/发送demo

    udp_group_rcv.c(接收端)demo:

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <netdb.h>
    #include <errno.h>
    
    #define BUFLEN 255
    
    int main(int argc, char **argv)
    {
    	struct sockaddr_in peeraddr;
    	struct in_addr ia;
    	int sockfd;
    	char recmsg[BUFLEN + 1];
    	unsigned int socklen, n;
    	struct hostent *group;
    	struct ip_mreq mreq;
    
    	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    	if (sockfd < 0) 
    	{
    		printf("socket creating err in udptalk\n");
    		exit(EXIT_FAILURE);
    	}
    
    
    	bzero(&mreq, sizeof(struct ip_mreq));
    	if (argv[1]) 
    	{
    		if ((group = gethostbyname(argv[1])) == (struct hostent *) 0) 
    		{
    			perror("gethostbyname");
    			exit(EXIT_FAILURE);
    		}
    	} 
    	else 
    	{
    		printf("you should give me a group address, 224.0.0.0-239.255.255.255\n");
    		exit(EXIT_FAILURE);
    	}
    
    	bcopy((void *) group->h_addr, (void *) &ia, group->h_length);
    	
    	bcopy(&ia, &mreq.imr_multiaddr.s_addr, sizeof(struct in_addr));
    
    	
    	//mreq.imr_interface.s_addr = htonl(INADDR_ANY);
    	if (argv[2]) {
    		if (inet_pton(AF_INET, argv[2], &mreq.imr_interface.s_addr) <= 0) 
    		{	
    			printf("Wrong dest IP address!\n");
    			exit(EXIT_FAILURE);
    		}
    	} 
    
    	
    	if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(struct ip_mreq)) == -1) 
    	{
    		perror("setsockopt");
    		exit(EXIT_FAILURE);
    	}
    
    	socklen = sizeof(struct sockaddr_in);
    	memset(&peeraddr, 0, socklen);
    	peeraddr.sin_family = AF_INET;
    	peeraddr.sin_port = htons(7838);
    	
    	if (argv[1]) {
    		if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0) 
    		{	
    			printf("Wrong dest IP address!\n");
    			exit(EXIT_FAILURE);
    		}
    	} 
    	else 
    	{
    		printf("no group address given, 224.0.0.0-239.255.255.255\n");
    		exit(EXIT_FAILURE);
    	}
    
    
    	if (bind(sockfd, (struct sockaddr *) &peeraddr,sizeof(struct sockaddr_in)) == -1) 
    	{
    		printf("Bind error\n");
    		exit(EXIT_FAILURE);
    	}
    
    
    	for (;;) 
    	{
    		bzero(recmsg, BUFLEN + 1);
    		n = recvfrom(sockfd, recmsg, BUFLEN, 0,(struct sockaddr *) &peeraddr, &socklen);
    		if (n < 0) 
    		{
    			printf("recvfrom err in udptalk!\n");
    			exit(EXIT_FAILURE);
    		} 
    		else 
    		{
    
    			recmsg[n] = 0;
    			printf("peer:%s", recmsg);
    		}
    	}
    } 
    
    

    udp_group_send.c(发送端)demo:

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define BUFLEN 255
    int main(int argc, char **argv)
    {
            struct sockaddr_in peeraddr, myaddr;
            int sockfd;
            char recmsg[BUFLEN + 1];
            unsigned int socklen;
            sockfd = socket(AF_INET, SOCK_DGRAM, 0);	
            if (sockfd < 0)
            {
                    printf("socket creating error\n");
                    exit(EXIT_FAILURE);
            }
            socklen = sizeof(struct sockaddr_in);
            memset(&peeraddr, 0, socklen);
            peeraddr.sin_family = AF_INET;
            peeraddr.sin_port = htons(7838);		
            if (argv[1]) {					
                    if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0) {
                            printf("wrong group address!\n");
                            exit(EXIT_FAILURE);
                    }
            } 
            else {
                    printf("no group address!\n");
                    exit(EXIT_FAILURE);
            }
            memset(&myaddr, 0, socklen);
            myaddr.sin_family = AF_INET;
            myaddr.sin_port = htons(23456);		
            if (argv[2]) {				
                    if (inet_pton(AF_INET, argv[2], &myaddr.sin_addr) <= 0) 
                    {
                            printf("self ip address error!\n");
                            exit(EXIT_FAILURE);
                    }
            } else
                    myaddr.sin_addr.s_addr = INADDR_ANY;
            if (bind(sockfd, (struct sockaddr *) &myaddr,sizeof(struct sockaddr_in)) == -1) 
            {								
                    printf("Bind error\n");
                    exit(EXIT_FAILURE);
            }
            for (;;) {
                    bzero(recmsg, BUFLEN + 1);
                    printf("input message to send:");
                    if (fgets(recmsg, BUFLEN, stdin) == (char *) EOF)	
                            exit(EXIT_FAILURE);;
                    if (sendto(sockfd, recmsg, strlen(recmsg), 0,(struct sockaddr *) &peeraddr,
    						sizeof(struct sockaddr_in)) < 0) 			
                    {
                            printf("sendto error!\n");
                           exit(EXIT_FAILURE);;
                    }
                    printf("sned message:%s", recmsg);	
            }
    }
    
    

    编译

    gcc udp_group_rcv.c -o udp_group_rcv
    gcc udp_group_send.c -o udp_group_send
    

    运行

    在这里插入图片描述

    展开全文
  • 组播又名多播 一、组播简介 组播(multicast,台湾又译作多点发送、多点广播或群播,中国大陆又...当以单播的形式把消息传递给多个接收方时,必须向每个接收者都发送一份数据副本。由此产生的多余副本将导致发送...
  • Java UDP 组播实现

    千次阅读 2016-06-27 10:34:43
    UDP(User Datagram Protocol,用户数据报协议)是传输层的另一种协议,它比TCP具有更快的传输速度,...当发送方先发送包含字符串“hello“的数据报,再发送包含字符串”everyone“的数据报,接收方有可能先接收到字符串
  • 数据接收端 效果展示 实现过程 Qt网络编程---UDP通信 工程中添加 QT += network QUdpSocket 数据发送端 1. 创建QUdpSocket对象 QUdpSocket msocket 2. 调用对象方法发送数据(ip , 端口号) ...
  • Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称...
  • UDP组播的实现 何为UDP广播 网络地址 组播发送步骤 组播接收步骤 完整例程: udp_add_multi_read.c udp_write.c 何为UDP广播 单播方式只能发给一个接收方,广播方式发给所有的主机。过多的广播会大量占用...
  • 台设备又要进行音视频数据的采集,同时又要担负对多台加入的设备进行实时推流的能力。显然在内存及并发推流能力上很快就已经进入到一个瓶颈了。 在用TCP进行推流的代码实现后,在实际的的测试过程中,在清晰度...
  • java UDP协议和组播实现 UDP(User Datagram Protocol,用户数据报协议)是传输层的另一种协议,它比TCP具有更快的传输速度,但是不可靠。 UDP发送的数据单元称为UDP数据报,当网络传输UDP数据报时,无法保证数据报...
  • 本实例通过采集麦克声音数据,利用udp组播方式在局域网中进行组播传送(类似在组内进行广播,udp广播、组播、单播请自行查阅相关资料),组内成员通过接收并播放到扬声器。 程序中引用了 Naudio 声音处理类库进行...
  • 单播,就像 两个人聊QQ 一样,信息的接收和传递只在两个节点之间进行。 多播(组播)。采用多播方式,既可以实现一次传送所有目标节点的数据,也可以达到只对特定对象传送数据的目的。 那么在QQ中,可以认为是 在QQ...
  • udp码流接收录制工具

    2020-05-26 17:02:40
    udp,rtp,ipv4,ipv6码流接收工具,可用于测试单播组播码流 接收UDP单播或者组播数据 接收rtp over udp数据 支持ipv4和ipv6 可选录制文件,文件可按照大小或者时间切分
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
    Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非...
  • 组播

    2019-01-17 23:38:00
    一、组播概述:(基于UDP) 在IP网络中,节点之间的通信通常采用...使用单播:需要向每一个接收者单独发送一份数据,当接收者数量增加时,发送源复制的工作负荷会比例增加,当接收数据巨大时,一些接收接收数据...
  • 组播程序示例

    2013-05-21 18:59:12
    2. 接收端bind绑定的地址与组播毫无关系,如果一个普通的udp发送端往接收端bind的地址值发数据接收端也可以收到,也就是说,一个用组播接收端,也可以收到单播数据! 3. 对组播的一些理解:发送端绑定一个网卡...
  • Linux 网络通信之组播

    2015-12-07 14:40:00
    组播可以看成是单播和广播的折中。当发送组播数据包时,只有加入指定多播组的主机数据链路层才会处理,其他主机在数据链路层会直接...组播包的发送和接收通过UDP套接字实现。 组播包发送流程如下: (1)创建UDP...
  • 组播协议笔记(一)

    2010-01-08 19:23:47
    组播优点: 一对多,同时发送数据给多个接收方。...组播缺点:基于UDP,尽力而为转发,无连接,不关心接收方是否能够收到。无序列号,传输时可能出现无序性,也缺乏流控功能。无窗口机制。导致收到重复组播流量...
  • 那么很容易理解就是,TCP是点对点的单播通信,只有UDP中才存在广播与组播。 广播 同时将数据发给局域网中的所有主机,称之为广播。 广播地址: 以192.168.1.0(255.255.255.0)为例子,最大的主机地址为:192.168.1...
  •   组播是一种介于单播和广播之间的方案,多播地址表示一组主机IP接口,多拨数据报只由对他感兴趣的接口接收组播可以在Internet和局域网使用。一个多播地址和一个UDP端口的组合称为组播会话(session)。 1.2 ...
  • 单播方式只能发给一个接收方。 广播方式发给所有的主机。过多的广播会大量占用网络带宽,造成广播风暴,影响正常的通信。 组播(又称为多播)是一种折中的方式。只有加入某个多播组的主机才能收到数据。 多播方式既可
  • 为什么UDP接收或发送会丢包

    千次阅读 2018-06-01 13:50:17
    摘自海思sdk内文档 BSP FAQ.docl 用户态应用程序在接收UDP数据时(单播播报文),同时进行其它有延时的操作(如写码流数据到USB存储设备), 应该程序将延迟接收UDP数据包,而socket默认接收缓存只有108544Byte,...
  • UDP广播/组播 功能 ★ 支持多Socket并行测试, 采用树状Socket可视化界面,所有Socket句柄一目了然 ★ 在一个程序内可进行多句柄/多类型的Socket的创建/删除/以及数据收发等操作 ★ 支持16进制的发送和16进制接收显示...
  • * 一台主机发送数据(通过UDP组播),其它主机接收 * 发送数据的主机开启8路组播端口,每路发送数据很均匀为51.2MBps。(总数据量为8x51.2Mbps) * 接收数据的主机同样开启8路组播端口接收数据。并同时保存数据,...
  • UDP Multicast

    2012-10-09 22:35:00
    组播是一对多的传输方式,其中有个组播组的概念,发送端将数据向一个组内发送,网络中的路由器通过底层的IGMP协议自动将数据发送到所有监听这个组的终端。至于广播则和组播有一些相似,区别是路由器向子网内的每一...
  • 广播与多

    2013-07-27 11:19:19
    多播介于单播与广播之间:帧仅传送给属于多播的多个主机 IP多播提供两类服务: 1)向多个目的地址传送数据。有许多向多个接收者传送信息的应用:例如交互式会议系统和向多个接收者分发邮件或新闻。如果不...

空空如也

1 2 3 4 5
收藏数 84
精华内容 33
关键字:

udp组播接收单播数据