linux网络编程--广播与组播

广播

  前面介绍的数据包发送方式只有一个接收方,称为单播

  如果发送给局域网中的所有主机,称为广播

  只有用户数据报(使用UDP协议)套接字才能广播

广播地址:

  以192.168.1.0(255.255.255.0)网段为例,最大的主机地址192.168.1.255代表该网段的广播地址

  发送该地址的数据包被所有主机接收

  255.255.255.255在所有网段中都代表广播地址

广播发送

  创建用户数据报套接字

  缺省创建的套接字不允许广播数据包,需要设置属性--setsockopt可以设置套接字属性

  接收方指定为广播地址

  指定端口信息

  发送数据包

设置套接口的选项:
  #include <sys/types.h>
  #include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
    sockfd:标识一个套接口的描述字。
    level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。
    optname:需设置的选项。
    optval:指针,指向存放选项待设置的新值的缓冲区
    optlen:optval缓冲区长度。
成功返回0,失败返回-1并设置errno
广播发送代码:
sockfd=socket()
......
int on=1
setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
.........
sendto(....);

广播接收:

创建用户数据报套接字

绑定ip地址(广播ip或0.0.0.0)和端口

  绑定的端口必须和发送方的指定的端口相同

等待接收数据

实例如下:

send.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define  err_log(errlog)  do{perror(errlog); exit(1);}while(0)
#define   N  128

// ./send 192.168.0.255 10000
int main(int argc, const char *argv[])
{
    int sockfd;
    struct sockaddr_in broadcastaddr;
    struct sockaddr_in clientaddr;
    socklen_t addrlen = sizeof(clientaddr);
    char buf[N] = {};

    if(argc < 3)
    {
        fprintf(stderr, "usage:%s serverip port.
", argv[0]);
        return -1;
    }

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        err_log("fail to socket");
    }

    broadcastaddr.sin_family = AF_INET;
    broadcastaddr.sin_addr.s_addr = inet_addr(argv[1]);
    broadcastaddr.sin_port = htons(atoi(argv[2]));

    int on = 1;

    if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
    {
        err_log("fail to setsockopt");
    }

    while(1)
    {
        printf("Input > ");
        fgets(buf, N, stdin);
        buf[strlen(buf)-1] = '