linux网络编程之广播编程

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

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


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

linux网络编程之广播编程_第1张图片

如何实现广播发送?

一般情况下使用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 LEN				256

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网络编程之广播编程_第2张图片

你可能感兴趣的:(linux,网络编程)