编辑:修改问题解释以使其更清晰。
我写了两个简单的程序:
客户端程序:将UDP组播数据包发送到 组播IP地址和端口。
服务器程序:请求组播IP的成员资格,绑定到同一端口并使用“recvfrom”接收这些数据包。它还打印出的内容 这些数据包与源地址和端口一起进入控制台。
现在,我在Machine_S上启动'server'程序,在Machine_C上启动'client'程序。两台机器都在同一个局域网中。
客户端的多播数据包到达Machine_S,我可以在Wireshark中看到它。 但是,“服务器”程序无法读取它们,即对 recvfrom 的调用不会返回。
现在,我在Machine_S上启动另一个'client'实例。一旦完成,'服务器'程序就开始从两个客户端(从两台机器)接收数据包并将它们打印到控制台!!
此时,即使我关闭Machine_S上的本地“客户端”实例,“服务器”仍将继续从Machine_C上的远程“客户端”接收数据包。
简而言之,只有当本地客户端也将数据包发送到同一个多播地址和端口时,服务器程序似乎才会从远程客户端接收数据包。
客户代码:
// COMMON MACROS FOR BOTH CLIENT AND SERVER
#define HELLO_PORT 12345
#define HELLO_GROUP "239.0.0.50"
// after initializing winsock
// create UDP socket
if ((sockid = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
printf("SOCKET Error Code: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
// set up destination address
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(HELLO_GROUP);
addr.sin_port = htons(HELLO_PORT);
// now just sendto() our destination!
while (times--) {
printf("Sent To : %d\n", HELLO_PORT);
if (sendto (sockid, message, strlen(message)+1, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
printf("SENDTO Error Code: %d\n", WSAGetLastError());
break;
}
Sleep(500);
}
closesocket(sockid);
WSACleanup();
服务器代码:
// create UDP socket
if ((sockid = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
printf("SOCKET Error Code: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
// set up local address
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl (INADDR_ANY);
addr.sin_port = htons (HELLO_PORT);
// bind to local address
if (bind(sockid, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
printf("BIND Error Code: %d\n", WSAGetLastError());
closesocket(sockid);
WSACleanup();
return 1;
}
// join a multicast group
mreq.imr_multiaddr.s_addr = inet_addr (HELLO_GROUP);
mreq.imr_interface.s_addr = htonl (INADDR_ANY);
if (setsockopt(sockid, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq)) < 0) {
printf("SETSOCKETOPT Error Code: %d\n", WSAGetLastError());
closesocket(sockid);
WSACleanup();
return 1;
}
memset(&addr,0,sizeof(addr));
// now just enter a read-print loop
while (times--) {
addrlen = sizeof(addr);
if ((nbytes = recvfrom(sockid, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *)&addr, &addrlen)) < 0) {
printf("RECVFROM Error Code: %d\n", WSAGetLastError());
break;
}
inet_ntop(AF_INET, &(addr.sin_addr), (PSTR)&address, MSGBUFSIZE);
srcport = ntohs(addr.sin_port);
printf("From\t%s\t%d\t", address, srcport);
puts(msgbuf);
Sleep(1000);
}
closesocket(sockid);
WSACleanup();
几点需要注意:
这可能是什么原因?