linux网络编程之广播编程

时间:2021-04-19 05:30:29

 广播方式主要是指使用UDP套接口发送数据,发送数据的目标地址不是普通的地址,而是所指定网络的广播地址。

 什么是广播地址?是指IP地址中主机地址部分全为1的IP地址。


下面是一个广播发送简单流程图。

linux网络编程之广播编程

如何实现广播发送?

一般情况下使用sendto函数只能向非广播地址发送数据,如果要发送广播数据就必须要告诉内核,可以通过设置套接字属性为SO_BROADCAST来坐到这一点。

int on = 1;

setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));


广播的缺点:

不管主机有没有程序在接收或者处理广播信息,广播信息一定会被网卡收到并提交给操作系统处理,所以会造成网络上数据流量增大,对不接收广播信息的主机造成一定的负担。


下面是一个简单的发送广播的程序。

服务端每隔3s发送一个广播信息,信息为系统当前的时间。

服务器端代码:

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

#define LEN256

void getTime(char *curTime)
{
time_t tm;
time(&tm);

snprintf(curTime, LEN, "%s\n", ctime(&tm));
}

int main(int argc, char **argv)
{
struct sockaddr_in peeraddr;
int sockfd = 0;
int on = 1;
int num = 0;

char msg[LEN] = {0};

if (argc != 3)
{
printf("Usage:%s<IP address> <PORT>\n", argv[0]);
return -1;
}

sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
printf("Create socket fails!\n");
return -1;
}

//设置套接字为广播模式 SO_BROADCAST
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

bzero(&peeraddr, sizeof(peeraddr));
peeraddr.sin_family = AF_INET;
if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0)
{
printf("IP address is error!\n");
return -1;
}
peeraddr.sin_port = htons(atoi(argv[2]));

for (;;)
{
getTime(msg);

num = sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&peeraddr, sizeof(struct sockaddr_in));

fflush(stdout);
sleep(3);
}

close(sockfd);

return 1;
}

客户端程序:

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

#define LEN 256

int main(int argc, char **argv)
{
struct sockaddr_in localaddr;
int sockfd = 0;
int num = 0;
char msg[LEN] = {0};

if (argc != 2)
{
printf("Usage: %s<PORT>\n", argv[0]);
return -1;
}

sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
printf("Create socket fails!\n");
return -1;
}

bzero(&localaddr, sizeof(localaddr));
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(atoi(argv[1]));
localaddr.sin_addr.s_addr = htonl(INADDR_ANY);

int opt = SO_REUSEADDR;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

if (bind(sockfd, (struct sockaddr *)&localaddr, sizeof(struct sockaddr_in)) < 0)
{
printf("bind fails!\n");
return -1;
}

num = read(sockfd, msg, LEN);
if (num <= 0)
{
printf("read message fails!\n");
return -1;
}

msg[num] = '\0';

printf("time:%s\n", msg);

close(sockfd);

return 1;
}
下面是简单的运行情况:

linux网络编程之广播编程