言之者无罪,闻之者足以戒。 - “诗序”
下面我们看一下播的分类:
(1)单播(unicast)
(2)任播(anycast)
(3)组播(multicast)
(4)广播(broadcast)
注意:广播和组播都需要使用UDP,都不能使用TCP
地址表示方式:
(1)IPv4地址的表示 {子网id , 主机id}
A/B/C/D/E五类地址,-1表示所有位都为1 的字段
(2)子网广播地址,{子网id ,-1},指定子网所有接口的广播地址
192.168.177.0/24 该子网上的广播地址192.168.177.255
(3)受限广播地地址 {-1 , -1}
255.255.255.255
单播UDP:
用户进程发送一组数据,经过数据链路之后通过网络直接发送给绑定地址的主机。
广播UDP:
用户进程发送一组数据,经过数据链路之后通过网络发送给当前在线的所有主机。
套接字和IP地址的宏设置表:
下面来看一下广播传输的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#define MAX_LISTEN_QUE 5
#define SERV_PORT 8888
#define MAXLEN 200
int main()
{
int sockfd;
struct sockaddr_in server;
struct sockaddr_in client;
struct sockaddr_in broadcast;
socklen_t addrlen,len;
int num;
time_t timep;
int opt = 1;
char read_buf[MAXLEN];
char buf[MAXLEN] = "hello.linux.";
//创建套接字
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("Creatingsocket failed.");
exit(1);
}
//设置允许广播发送
if(setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(opt)) < 0){
perror("create error\n");
return -1;
}
//初始化server结构体
bzero(&server,sizeof(server));
server.sin_family=AF_INET;//IPv4
server.sin_port=htons(SERV_PORT);//端口号
server.sin_addr.s_addr= htonl (INADDR_ANY);//设置为可以连接任何一个客户端
//初始化broadcast结构体
bzero(&broadcast,sizeof(broadcast));
broadcast.sin_family=AF_INET;//IPv4
broadcast.sin_port=htons(SERV_PORT);//端口号
broadcast.sin_addr.s_addr= inet_addr ("192.168.177.128");//设置为可以连接任何一个客户端
//将套接字和服务器的地址绑定
if(bind(sockfd, (struct sockaddr *)&server, sizeof(server)) == -1)
{
perror("Bind()error.");
exit(1);
}
//得到存储客户端的结构体的长度
addrlen=sizeof(client);
//获得broadcast结构体的长度
len = sizeof(struct sockaddr_in);
//将数组中的内容发送到broadcast中
num = sendto(sockfd,buf,strlen(buf),0,
(struct sockaddr *)&broadcast,len);
if(num < 0){
perror("sendto error\n");
return -1;
}
while(1)
{
//从客户端读取数据,并存储在read_buf中
num =recvfrom(sockfd,read_buf,MAXLEN,0,(struct sockaddr*)&client,&addrlen);
if (num < 0)
{
perror("recvfrom() error\n");
exit(1);
}
//最后一个字符为空(防止打出乱码)
read_buf[num] = '\0';
//打印读取的内容以及ip地址和端口号
printf("You got a message (%s%) from client.\nIt's ip is%s, port is %d.\n"
,read_buf,inet_ntoa(client.sin_addr),htons(client.sin_port));
//获取时间的函数
timep = time(NULL);
snprintf(buf, sizeof(buf), "%s", ctime(&timep));
//发送数据到广播报
sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&broadcast,len);
//清空客户端和数组
bzero(&client, len);
bzero(buf, MAXLEN);
bzero(read_buf, MAXLEN);
sleep(1);
}
//关闭套接字
close(sockfd);
return 0;
}
运行结果如下: