我寫了一個廣播電臺和一個聽衆其中recvfrom系統上的一個特定端口。我在聽衆中使用了REUSEADDR選項,以使聽衆的多個實例監視同一系統上的相同端口。同一臺機器上的UDP廣播?
當我在不同的機器上運行聽衆,並從另一臺機器發送數據包,所有的聽衆接收包。但是當我在同一臺機器上運行聽衆的多個實例,並且如果我嘗試發送udp數據包,則只有聽衆的第一個實例獲取該數據包不是全部。我想在同一臺機器上廣播UDP數據包,並希望所有偵聽器都能收到數據包。我在Linux上。
我遵循了Beej的指南。
編輯01
監聽器代碼
/*
** listener.c -- a datagram sockets "server" demo
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#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(int argc, char *argv[])
{
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 reuse_addr = 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 (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
if(errno == EADDRINUSE)
{
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
&reuse_addr, sizeof reuse_addr) < 0)
perror("setsockopt(): REUSEADDR\n"),exit(1);
}
else
{
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地址是您的發件人發送到?如果它發送到127.0.0.1,那麼它發送單播數據包,並且只有一個監聽器會接收它們。如果它發送到本地網絡的廣播地址(例如,如果您位於192.168.0.x網絡上,則爲192.168.0.255;如果位於10.0.xy網絡上,則爲10.255.255.255等),則所有偵聽器應該收到數據包。 –
我試圖發送到255.255.255.255,本地主機和0.0.0.0。在所有情況下,只有一個聽衆獲得該分組。 – selvakumar
嘗試你局域網的廣播地址(這基本上是你的IP地址按位或不是你的網絡掩碼;例如ip = 192.168.2.5 netmask = 255.255.255.0,broadcast_address =(192.168.2.5 | 0.0.0.255 )= 192.168.2.255 –