首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UDP组播未收到消息

UDP组播未收到消息
EN

Stack Overflow用户
提问于 2015-08-18 05:59:11
回答 2查看 4.1K关注 0票数 3

我正在尝试制作一个简单的UDP多播示例,其中从一个程序发送消息,从另一个程序接收消息,但现在输出仅为:

代码语言:javascript
复制
Connected
Message Sent

代码语言:javascript
复制
bind
setup multicast

有人能告诉我我遗漏了什么吗?这样我才能成功地接收到这条消息?谢谢你!!下面是完整的代码:

代码语言:javascript
复制
int main(int argc, char *argv[])
{

int udp_socket_info;
struct sockaddr_in udp_server;
char* message="test";

    //create socket
    udp_socket_info = socket(AF_INET, SOCK_DGRAM, 0);
    if (udp_socket_info == -1) {
    puts("Could not create socket");
    }

//assign local values
    udp_server.sin_addr.s_addr = inet_addr("225.0.0.37"); //multicast address
    udp_server.sin_family = AF_INET;
    udp_server.sin_port = htons( 1100 );

    //checks connection 
    if (connect(udp_socket_info, (struct sockaddr *)&udp_server, sizeof(udp_server)) < 0) {
    perror("Connection error");
    }
    puts("Connected");

    //sends message
    if( sendto(udp_socket_info , message , strlen(message) , 0, (struct sockaddr *)&udp_server, sizeof(udp_server)) < 0) {     
perror("Send failed");
    }
    puts("Message Sent");

}

第二个程序是

代码语言:javascript
复制
int main(int argc, char *argv[])
{

//initialize udp socket and structures
int udp_socket_info;
struct sockaddr_in udp_server;
struct sockaddr addr;
struct ip_mreq mreq;
socklen_t fromlen;
fromlen = sizeof addr;
char incoming_message[100];

    //create udp socket
    udp_socket_info = socket(AF_INET, SOCK_DGRAM, 0);
    if (udp_socket_info == -1) {
    puts("Could not create socket");
        }

    // set up 
memset((char*)&udp_server,0,sizeof(udp_server));
    udp_server.sin_family=AF_INET;
    udp_server.sin_port = htons( 1100 );
udp_server.sin_addr.s_addr = inet_addr("192.168.0.100"); //local address

    // bind 
    if (bind(udp_socket_info,(struct sockaddr *)&udp_server, sizeof(udp_server)) < 0) {
  perror("bind error");
  exit (1);
      }
puts("bind");

 // use setsockopt() to join multicast group
 mreq.imr_multiaddr.s_addr=inet_addr("225.0.0.37"); //multicast address
 mreq.imr_interface.s_addr= htonl(INADDR_ANY); //can use local address here too
 if (setsockopt(udp_socket_info, IPPROTO_IP,IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
  perror("setsockopt");
  exit (1);
      }
puts("setup multicast");

    //Receive an incoming message
    if( recvfrom(udp_socket_info, incoming_message , sizeof(incoming_message), 0, &addr, &fromlen) < 0) {
puts("Received failed");
exit (1);
    }
    puts("Message received");
    puts(incoming_message);
}
EN

回答 2

Stack Overflow用户

发布于 2015-08-18 07:56:14

您应该将接收套接字绑定到INADDR_ANY,而不是本地接口地址。否则,您将冒着发送者通过不同的路由到达您的套接字的风险。在某些平台上,您可以将其绑定到组播地址本身。

注意当你得到一个错误时,仅仅打印你自己设计的消息是不够的。消息必须包含errnostrerror()的结果。例如,调用perror()

票数 2
EN

Stack Overflow用户

发布于 2015-08-18 09:52:50

您的接收方不应绑定到本地地址。相反,它应该绑定到INADDR_ANY或您打算加入的组播地址。绑定到本地地址会中断Linux系统上的多播。

请注意,如果您绑定到一个多播地址,这意味着您将只接收该多播地址的数据包。如果您想接收来自多个多播地址的数据包,或者如果您还想接收单播数据包,那么您需要绑定到INADDR_ANY

加入组播组时,使用INADDR_ANY会导致您加入默认网络接口上的指定组。通常,显式指定一个接口是一个好主意。

正如EJP提到的,您应该始终使用perror来打印来自任何系统或库调用的错误消息,以确保打印出有意义的错误消息。

Wireshark是这类程序的重要工具。它可以帮助您确保数据包在您期望的网络接口中进出。

此外,如果发送方和接收方位于不同的网段,则需要通过IP_MULTICAST_TTL套接字选项设置TTL。您还需要确保它们之间的所有路由器都配置为传递组播流量。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32060387

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档