
C语言如何进行UDP广播:使用socket创建、配置广播选项、发送和接收广播消息
在计算机网络编程中,UDP广播是一种常见的技术,用于在局域网内发送数据包给所有主机。在C语言中实现UDP广播主要涉及到创建socket、配置广播选项、发送和接收广播消息等步骤。创建socket、设置SO_BROADCAST选项、构建广播地址、发送数据包、接收广播消息是实现UDP广播的关键步骤。以下将详细介绍这些步骤,并提供具体的代码示例。
一、创建socket
创建socket是进行UDP广播的第一步。通过调用socket函数,可以创建一个用于通信的socket。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main() {
int sock;
struct sockaddr_in broadcastAddr;
char *broadcastIP = "255.255.255.255"; // 广播地址
unsigned short broadcastPort = 37020; // 广播端口
char *sendString = "Hello, UDP Broadcast!"; // 广播消息
int broadcastPermission;
int sendStringLen;
// 创建UDP socket
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("socket() failed");
exit(1);
}
// 设置广播选项
broadcastPermission = 1;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcastPermission,
sizeof(broadcastPermission)) < 0) {
perror("setsockopt() failed");
exit(1);
}
// 构建广播地址
memset(&broadcastAddr, 0, sizeof(broadcastAddr));
broadcastAddr.sin_family = AF_INET;
broadcastAddr.sin_addr.s_addr = inet_addr(broadcastIP);
broadcastAddr.sin_port = htons(broadcastPort);
// 发送广播消息
sendStringLen = strlen(sendString);
if (sendto(sock, sendString, sendStringLen, 0, (struct sockaddr *)
&broadcastAddr, sizeof(broadcastAddr)) != sendStringLen) {
perror("sendto() sent a different number of bytes than expected");
exit(1);
}
close(sock);
return 0;
}
二、设置SO_BROADCAST选项
为了使socket能够发送广播消息,必须设置SO_BROADCAST选项。通过调用setsockopt函数,可以为socket设置广播权限。
broadcastPermission = 1;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcastPermission,
sizeof(broadcastPermission)) < 0) {
perror("setsockopt() failed");
exit(1);
}
三、构建广播地址
广播地址是一个特殊的IP地址,通常为255.255.255.255,表示局域网内的所有主机。需要使用inet_addr函数将广播IP地址转换为网络字节序,并将其设置到sockaddr_in结构体中。
memset(&broadcastAddr, 0, sizeof(broadcastAddr));
broadcastAddr.sin_family = AF_INET;
broadcastAddr.sin_addr.s_addr = inet_addr(broadcastIP);
broadcastAddr.sin_port = htons(broadcastPort);
四、发送数据包
通过调用sendto函数,可以将数据包发送到指定的广播地址。注意,发送的数据包长度应该与预期发送的长度一致。
sendStringLen = strlen(sendString);
if (sendto(sock, sendString, sendStringLen, 0, (struct sockaddr *)
&broadcastAddr, sizeof(broadcastAddr)) != sendStringLen) {
perror("sendto() sent a different number of bytes than expected");
exit(1);
}
五、接收广播消息
为了接收广播消息,需要在另一端创建一个UDP socket并绑定到相同的广播端口。然后,通过调用recvfrom函数,可以接收来自网络的广播消息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define MAXRECVSTRING 255 // 最大接收字符串长度
int main() {
int sock;
struct sockaddr_in broadcastAddr;
char recvString[MAXRECVSTRING + 1]; // 接收字符串缓冲区
int recvStringLen;
unsigned short broadcastPort = 37020; // 广播端口
// 创建UDP socket
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("socket() failed");
exit(1);
}
// 构建接收地址
memset(&broadcastAddr, 0, sizeof(broadcastAddr));
broadcastAddr.sin_family = AF_INET;
broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY);
broadcastAddr.sin_port = htons(broadcastPort);
// 绑定到广播端口
if (bind(sock, (struct sockaddr *) &broadcastAddr, sizeof(broadcastAddr)) < 0) {
perror("bind() failed");
exit(1);
}
// 接收广播消息
while (1) {
if ((recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0)) < 0) {
perror("recvfrom() failed");
exit(1);
}
recvString[recvStringLen] = '