奇怪的多播UDP数据包接收(recvfrom)

时间:2014-07-14 10:20:47

标签: c++ sockets udp winsock multicast

编辑:修改问题解释以使其更清晰。

我写了两个简单的程序:

  1. 客户端程序:将UDP组播数据包发送到 组播IP地址和端口。

  2. 服务器程序:请求组播IP的成员资格,绑定到同一端口并使用“recvfrom”接收这些数据包。它还打印出的内容 这些数据包与源地址和端口一起进入控制台。

  3. 现在,我在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();
    

    几点需要注意:

    • 每台机器只有1个网络接口
    • 组播IP为239.0.0.50,端口为12345

    这可能是什么原因?

0 个答案:

没有答案