用UDP通信实现广播接收数据:
广播流程(bcast.c, bcastrecv .c)
- 创建UDP套接字 socket(AF_INET, SOCK_DGRAM, 0)
- 开启广播 int on=1; setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, on, sizeof(on));
- 发送数据给广播地址 sendto(sockfd, 发送的数据data, 数据长度size, 0, 广播地址, 地址长度)
函数:
//开启广播
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
注意:void *optval和const void *optval的区别
加const是传入参数,没加const不一定是传出参数,传入传出都可以(如果传入的参数要修改,就不能加const)
参数: int sockfd 套接字描述符
int level: 级别socket(SOL_SOCKET), IP,TCP(IPPROTO_IP)定义在socket.h文件中(man 7 socket)
int optname 这个参数与level对应,如果level为SOL_SOCKET,本参数
(Ctrl+括号的右边查看宏定义,ctrl+o返回)
const void *optval 要设置的值(比如设置广播: 1-开, 0-关闭)
socklen_t optlen 值占用空间大小
实现完整代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(void)
{
//1.创建套接字
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0)
{
perror("socket fail");
return -1;
}
//开启广播
int on =1;
int ret = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
if(ret < 0) perror("setsockopt error");
//2.发送数据
struct sockaddr_in destAddr; //定一个存储地址,端口号的替代结构体
memset(&destAddr, 0, sizeof(destAddr)); //初始化为0
destAddr.sin_family = AF_INET;//初始化地址族IPV4
destAddr.sin_port = htons(9999); //设置端口号(网络字节序号)
destAddr.sin_addr.s_addr = inet_addr("192.168.24.255");//初始化绑定地址, 用INADDR_ANY--表示绑定本机地址
char sendbuffer[]="教师机hello world";
ssize_t size = sendto(sockfd, sendbuffer, sizeof(sendbuffer), 0, (struct sockaddr*)&destAddr, sizeof(destAddr));
if(size <0){
perror("sendto error");
close(sockfd);
return -1;
}
#if 0
//接收反馈数据
char recvbuffer[1024];
size = recvfrom(sockfd, recvbuffer, sizeof(recvbuffer), 0, NULL, NULL);
if(size < 0)
{
perror("recvfrom error");
return -1;
}
printf("%s\n", recvbuffer);
#endif
close(sockfd);
}
接收数据端:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXSIZE 100
int main(void)
{
//1.创建套接字 UDP--SOCK_DGRAM
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0)
{
perror("socket fail");
return -1;
}
//设置地址复用
int on = 1;
int ropt = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
//2.绑定
struct sockaddr_in addr; //定一个存储地址,端口号的替代结构体
memset(&addr, 0, sizeof(addr)); //初始化为0
addr.sin_family = AF_INET;//初始化地址族IPV4
addr.sin_port = htons(9999); //设置端口号(网络字节序号)
addr.sin_addr.s_addr = INADDR_ANY;//初始化绑定地址, 用INADDR_ANY--表示绑定本机地址
int ret = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
if(ret < 0)
{
perror("bind fail:");
return -1;
}
//3.接收数据
struct sockaddr_in srcAddr;//保存发送方的地址
socklen_t len = sizeof(srcAddr);
char recvbuffer[1024];
ssize_t size = recvfrom(sockfd, recvbuffer, sizeof(recvbuffer), 0, (struct sockaddr*)&srcAddr, &len);
if(size < 0)
{
perror("recvfrom error");
return -1;
}
printf("%s\n", recvbuffer);
//关闭套接字
close(sockfd);
return 0;
}