【linux网络编程学习笔记】第八节:UDP广播的实现

本文介绍了Linux网络编程中UDP广播的概念,包括广播地址、发送步骤,并提供了两个完整例程:udp_broadcast.c(发送端)和udp_read.c(接收端)。通过设置SO_BROADCAST选项,使得UDP套接字能够发送广播数据包。

Where there is life, there is hope.

  有生命必有希望

UDP广播的实现

何为UDP广播

广播地址

广播发送步骤

完整例程:udp_broadcase.c

 完整例程:udp_read.c


何为UDP广播

         前面章节介绍的数据包发送方式只有一个接受方,称为单播,如果同时发给局域网中的所有主机,称为广播。注意,只有用户数据报(使用UDP协议)套接字才能广播。

广播地址

        广播UDP与单播UDP的区别就是IP地址不同,广播使用广播地址255.255.255.255。以192.168.1.0 (255.255.255.0) 网段为例,最大的主机地址192.168.1.255代表该网段的广播地址,发到该地址的数据包被所有的主机接收,255.255.255.255在所有网段中都代表广播地址。

广播发送步骤

  1. 创建用户数据报套接字
  2. 缺省创建的套接字不允许广播数据包,需要设置属性setsockopt可以设置套接字属性
  3. 接收方地址指定为广播地址
  4. 指定端口信息
  5. 发送数据包

其中最主要的就是设置socket的属性,如何设置,有哪些属性前面的章节已经罗列了,点击跳转

广播的选项:SO_BROADCAST

  • 设置或获取广播标志。启用后,允许数据报套接字将数据包发送到广播地址。该选项没有对面向流的套接字的影响。
int sw = 1;//1为打开开关

int retval = setsockopt(udp_fd, SOL_SOCKET, SO_BROADCAST, &sw, sizeof(sw));
if(retval == -1)
{
    perror("设置程序允许广播出错");
    close(udp_fd);
    return -1;
}

其他的步骤实现和普通的UDP程序一样,点击跳转

完整例程:udp_broadcase.c

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>
#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>

struct msg_info{
	char name[256];
	char msg[1024];
};


int main(int argc, const char *argv[])
{

	if(argc != 3)
	{
		printf("用法格式错误,标准格式:./可执行文件 用户名 目标端口号\n");
		return -1;
	}

	char buffer[1024];
	int udp_fd;
	int retval;
	ssize_t send_size;
	struct msg_info msg;
	struct sockaddr_in dest_addr, recv_addr;
	socklen_t skt_len = sizeof(struct sockaddr_in);

	strcpy(msg.name,argv[1]);

	udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
	if(udp_fd == -1)
	{
		perror("申请套接字失败");
		close(udp_fd);
		return -1;
	}
	
	int sw = 1;

	retval = setsockopt(udp_fd, SOL_SOCKET, SO_BROADCAST, &sw, sizeof(sw));
	if(retval == -1)
	{
		perror("设置程序允许广播出错");
		close(udp_fd);
		return -1;
	}

	dest_addr.sin_family = AF_INET;
	dest_addr.sin_port = htons(atoi(argv[2]));
	dest_addr.sin_addr.s_addr = inet_addr("192.168.32.255");

	while(1)
	{
		scanf("%s", msg.msg);

		send_size = sendto(udp_fd, &msg, (strlen(msg.msg)+sizeof(msg.name)), 
			0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
		if(send_size == -1)
		{
			perror("发送UDP数据失败\n");
			break;
		}
		
	}

	close(udp_fd);


	return 0;
}

 完整例程:udp_read.c

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>
#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>

struct msg_info{
	char name[256];
	char msg[1024];
};


int main(int argc, const char *argv[])
{
	if(argc != 3)
	{
		printf("用法格式错误,标准格式:./可执行文件 用户名 本地端口号\n");
		return -1;
	}

	char buffer[1024];
	int udp_fd;
	int retval;
	ssize_t recv_size;
	struct msg_info msg;
	struct sockaddr_in native_addr, recv_addr;
	socklen_t skt_len = sizeof(struct sockaddr_in);

	strcpy(msg.name,argv[1]);

	udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
	if(udp_fd == -1)
	{
		perror("申请套接字失败");
		return -1;
	}

	native_addr.sin_family = AF_INET;
	native_addr.sin_port = htons(atoi(argv[2]));
	native_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	retval = bind(udp_fd, (struct sockaddr *)&native_addr, sizeof(native_addr));
	if(retval == -1)
	{
		perror("绑定对应的ip地址及端口失败");
		close(udp_fd);
		return -1;
	}


	while(1)
	{
		bzero(&msg, sizeof(msg));

		recv_size = recvfrom(udp_fd, &msg, sizeof(msg), 
			0, (struct sockaddr *)&recv_addr, &skt_len);
		if(recv_size == -1)
		{
			perror("接受UDP数据失败\n");
			break;
		}

		printf("读取到 %s 的 %ld 字节的数据:%s\n",msg.name, recv_size, msg.msg);
		
	}

	close(udp_fd);


	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值