我正在尝试创建一个简单的UDP多播示例,其中一个消息从一个程序发送并从另一个程序接收,但此时输出仅为:
Connected
Message Sent
和
bind
setup multicast
有人可以告诉我我失踪了什么,以便我能成功收到消息吗?谢谢!!以下是完整的代码:
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");
}
,第二个程序是
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);
}
答案 0 :(得分:1)
您应该将接收套接字绑定到INADDR_ANY,而不是本地接口地址。否则,您将面临发件人通过其他路由到达的风险,并且无法访问您的套接字。在某些平台上,您可以将其绑定到多播地址本身。
注意当您收到错误时,打印您自己设计的消息是不够的。邮件必须包含errno
或strerror()
的结果。例如,请致电perror()
。
答案 1 :(得分:1)
您的接收方不应绑定到本地地址。它应该绑定到INADDR_ANY
或您打算加入的多播地址。绑定到本地地址会破坏Linux系统上的多播。
请注意,如果绑定到多播地址,则表示您只接收该多播地址的数据包。如果您想从多个多播地址接收,或者您还想接收单播数据包,则需要绑定到INADDR_ANY
。
加入多播组时,使用INADDR_ANY会导致您加入默认网络接口上的指定组。明确指定接口通常是个好主意。
正如EJP所提到的,您应该始终使用perror来打印来自任何系统或库调用的错误消息,以确保打印出有意义的错误消息。
Wireshark是此类程序的重要工具。它可以帮助您确保数据包流出并进入您期望的网络接口。
此外,如果发件人和收件人位于不同的网段,则需要通过IP_MULTICAST_TTL套接字选项设置TTL。您还需要确保它们之间的任何路由器都配置为传递多播流量。