[英]C Application not recieving Multicast
我正在嘗試創建一個應用程序,它使用多播與本地網絡上的應用程序的其他實例通信(應用程序應該在 windows 和 linux 下工作)。
我是多播的新手,所以我嘗試使用在互聯網上找到的以下代碼:
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#define EXAMPLE_PORT 6000
#define EXAMPLE_GROUP "239.124.0.1"
// If argc == 0, recieve, else send
int main(int argc, char**argv)
{
struct sockaddr_in addr;
socklen_t addrlen = 0;
int sock = 0, cnt = 0;
struct ip_mreq mreq;
char message[50];
/* set up socket */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("socket");
exit(1);
}
bzero((char *)&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(EXAMPLE_PORT);
addrlen = sizeof(addr);
if (argc > 1) {
/* send */
addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP);
while (1) {
time_t t = time(0);
sprintf(message, "time is %-24.24s", ctime(&t));
printf("sending: %s\n", message);
cnt = sendto(sock, message, sizeof(message), 0,
(struct sockaddr *) &addr, addrlen);
if (cnt < 0) {
perror("sendto");
exit(1);
}
sleep(5);
}
} else {
/* receive */
if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
mreq.imr_multiaddr.s_addr = inet_addr(EXAMPLE_GROUP);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof(mreq)) < 0) {
perror("setsockopt mreq");
exit(1);
}
while (1) {
cnt = recvfrom(sock, message, sizeof(message), 0,
(struct sockaddr *) &addr, &addrlen);
if (cnt < 0) {
perror("recvfrom");
exit(1);
} else if (cnt == 0) {
break;
}
printf("%s: message = \"%s\"\n", inet_ntoa(addr.sin_addr), message);
}
}
}
該代碼成功發送了我可以在我的 android 手機上接收到的多播數據包(通過編譯完全相同的代碼並使用 Termux 編譯/執行)。
所以我知道代碼正在運行。 但這是我的問題:在 linux 和 windows 上,我無法收到數據包。 我可以發送它們(我的手機確實收到了來自兩者的數據包),但我無法接收。
令我驚訝的是,它與我的 linux 和 android 上的代碼完全相同(在 windows 上,只有一些使用 winsock2 的修改)。
此外,我可以看到我的linux確實收到了數據包:
$ sudo tcpdump -i wlp58s0 host 239.124.0.1
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlp58s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:36:59.196616 IP 192.168.1.10.48727 > 239.124.0.1.6000: UDP, length 50
12:37:04.112507 IP 192.168.1.10.48727 > 239.124.0.1.6000: UDP, length 50
12:37:09.129963 IP 192.168.1.10.48727 > 239.124.0.1.6000: UDP, length 50
^C
4 packets captured
4 packets received by filter
0 packets dropped by kernel
192.168.1.10 是我在該網絡上的電話 IP 地址。
還可以看到我成功加入了組播組:
$ netstat -gn | grep 239.124.0.1
wlp58s0 1 239.124.0.1
所以我的問題是為什么我不能在 linux/windows 上接收多播數據包?
我需要更改我的代碼以接收它們嗎?
對於接收方,此代碼加入接口 0.0.0.0 上的多播組(指定為INADDR_ANY
)。 這意味着它加入了被認為是默認接口的網絡接口。 如果這不是接收多播流量的同一個接口,您將不會收到數據包。
您正在接口 wlp58s0 上接收數據包,因此請查看該接口使用的 IP 地址,並在選擇要綁定的接口時使用該 IP。
例如,如果 wlp58s0 具有 IP 地址 192.168.1.2,則更改此:
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
對此:
mreq.imr_interface.s_addr = inet_addr("192.168.1.2");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.