让同一个端口号,既可以接收单播也可以接收组播的方法!
/*************************************************************************
> File Name: udp.c
> Author: huochuanfei
> Mail: 597092440@qq.com
> Created Time: 2021-05-21 14:22:28
************************************************************************/
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <linux/sockios.h>
#include <linux/if.h>
#include <stdlib.h>
int sockfd = 0;
/**********************************************
* function: create_mul_fd
* Author: huochuanfei
* Mail: 597092440@qq.com
* Created Time: 2020-11-10
*********************************************/
static int create_mul_fd(int port, uint32_t ip)
{
int fd = 0;
int loop = 1;
struct ifreq ifq;
struct ip_mreq mreq;
struct sockaddr_in addr;
memset((char*)&addr, 0x0, sizeof(struct sockaddr_in));
strncpy(ifq.ifr_name, "wlp3s0", IFNAMSIZ);
if ((fd = socket(AF_INET, SOCK_DGRAM ,0)) <= 0) {
printf("socket:%m\n");
exit(1);
}
int yes = 1;
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);/* 很关键,不能绑定具体IP */
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
printf("setsockopt");
exit(1);
}
if (bind(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr)) < 0) {
printf("bind2:%m\n");
exit(1);
}
mreq.imr_multiaddr.s_addr = ip;
mreq.imr_interface.s_addr = inet_addr("192.168.1.66");
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
printf("setsockopt");
exit(1);
}
return fd;
}
int main() {
sockfd = create_mul_fd(9999, inet_addr("224.9.9.9"));
if (sockfd < 0) {
printf("listen_mult: %d\n", sockfd);
return -1;
}
char buf[1024] = {0};
int ret = 0;
while (1) {
memset(buf, 0x0, sizeof(buf));
ret = recv(sockfd, buf, sizeof(buf), 0);
printf("%d: %s\n", ret, buf);
}
return 0;
}