如何使用UDP套接字在本地广播消息?
如何使用UDP套接字在本地广播消息?
我想在本地向多个应用程序广播消息。 为此,我认为UDP套接字是最好的IPC,如果我错了,请纠正我。
为此,我正在使用以下代码:
用于广播:
/* ** broadcaster.c -- a datagram "client" that can broadcast */ #include #include #include #include #include #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include #define SERVERPORT 4950 // the port users will be connecting to int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in their_addr; // connector's address information struct hostent *he; int numbytes; int broadcast = 1; //char broadcast = '1'; // if that doesn't work, try this if (argc != 3) { fprintf(stderr,"usage: broadcaster hostname message\n"); exit(1); } if ((he=gethostbyname(argv[1])) == NULL) { // get the host info perror("gethostbyname"); exit(1); } if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1); } // this call is what allows broadcast packets to be sent: if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast) == -1) { perror("setsockopt (SO_BROADCAST)"); exit(1); } their_addr.sin_family = AF_UNIX; // host byte order their_addr.sin_port = htons(SERVERPORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero); if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0, (struct sockaddr *)&their_addr, sizeof their_addr)) == -1) { perror("sendto"); exit(1); } printf("sent %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr)); close(sockfd); return 0; }
听取:
/* ** listener.c -- a datagram sockets "server" demo */ #include #include #include #include #include #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include #define MYPORT "4950" // the port users will be connecting to #define MAXBUFLEN 100 // get sockaddr, IPv4 or IPv6: void *get_in_addr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); } int main(void) { int sockfd; struct addrinfo hints, *servinfo, *p; int rv; int numbytes; struct sockaddr_storage their_addr; char buf[MAXBUFLEN]; socklen_t addr_len; char s[INET6_ADDRSTRLEN]; int optval = 1; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("listener: socket"); continue; } if(setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR, &optval, sizeof optval) != 0) { perror("listener: setsockopt"); continue; } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("listener: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "listener: failed to bind socket\n"); return 2; } freeaddrinfo(servinfo); printf("listener: waiting to recvfrom...\n"); addr_len = sizeof their_addr; if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1); } printf("listener: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s)); printf("listener: packet is %d bytes long\n", numbytes); buf[numbytes] = '\0'; printf("listener: packet contains \"%s\"\n", buf); close(sockfd); return 0; }
问题是我必须像这样传递IP 192.168.1.255,但在实际情况中可能没有eth0接口,只会有环回。 那么我该如何实现这一点?
admin 更改状态以发布 2023年5月23日
服务器不应该绑定到从getaddrinfo
得到的地址,而应该绑定到127.255.255.255
(用于回环接口)。
要获取现成的广播服务器/客户端示例,请参见http://www.ccplusplus.com/2011/09/udp-broadcast-client-server-example.html