gpt4 book ai didi

c - 无法从多播组获取数据

转载 作者:行者123 更新时间:2023-11-30 19:29:57 24 4
gpt4 key购买 nike

这是怎么回事,如果某个组的成员发送了数据,那么他们的程序为什么不接收它呢?如果一切正常,请调试代码。当我运行该程序时,会出现一个新的组,使用ip -s maddr可以很容易地进行检查。

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <ifaddrs.h>
#include <ctype.h>

char in[IFNAMSIZ];
const char *multi = "224.0.0.1";
const short port = 0;

static int
init_socket ( )
{
int sock = socket ( AF_INET, SOCK_DGRAM, 0 );

int ret;
struct ifreq ifr;
memset ( &ifr, 0, sizeof ifr );
strncpy ( ifr.ifr_name, in, strlen ( in ) );
ret = ioctl ( sock, SIOCGIFADDR, &ifr );
if ( ret == -1 ) {
perror ( "SIOCGIFADDR" );
printf ( "%s\n", in );
exit ( EXIT_FAILURE );
}

struct ip_mreqn ip;
inet_aton ( multi, &ip.imr_multiaddr );
memcpy ( &ip.imr_address,
&( ( struct sockaddr_in * ) &ifr.ifr_addr)->sin_addr,
sizeof ( struct in_addr ) );

ip.imr_ifindex = if_nametoindex ( ifr.ifr_name );

struct sockaddr_in s;
memset ( &s, 0, sizeof s );
s.sin_family = AF_INET;
memcpy ( &s.sin_addr,
&( ( struct sockaddr_in * ) &ifr.ifr_addr)->sin_addr,
sizeof ( struct in_addr ) );
s.sin_port = htons ( port );

const int on = 1;
ret = setsockopt ( sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on );
if ( ret == -1 ) {
perror ( "setsockopt so_reuseaddr" );
exit ( EXIT_FAILURE );
}

ret = setsockopt ( sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ip, sizeof ip );
if ( ret == -1 ) {
perror ( "setsockopt ip_add_membership" );
exit ( EXIT_FAILURE );
}

// bind ( sock, ( struct sockaddr * ) &s, sizeof ( s ) );
return sock;
}
const int length = 16384;
void *reader ( void *data )
{
int sock = *( (int *) data );
char buf [ length ];
while ( 1 ) {
read ( sock, buf, length );
printf ( "%s\n", buf );
}
}

static int
check_buf ( const char *b )
{
for ( ; *b != 0; b++ ) {
if ( *b == 10 || *b == 13 ) continue;
if ( !isdigit ( *b ) ) {
return -1;
}
}
return 0;
}
static void
get_interface ( )
{
struct ifaddrs *ifs, *ifa;
if ( getifaddrs ( &ifs ) == -1 ) {
perror ( "getifaddrs" );
exit ( EXIT_FAILURE );
}
char buf[10];

int n = 0;
while ( in[0] == 0 ) {
int number = 1;
for ( ifa = ifs; ifa != NULL; ifa = ifa->ifa_next, number++ ) {
if ( ifa->ifa_addr == NULL ) continue;
int family = ifa->ifa_addr->sa_family;

if ( family == AF_INET ) {
if ( n == 0 ) printf ( "%d: %s\n", number, ifa->ifa_name );
}
if ( n == number ) {
strncpy ( in, ifa->ifa_name, strlen ( ifa->ifa_name ) );
return;
}
}
fgets ( buf, 10, stdin );
int ret = check_buf ( &buf[0] );
if ( ret != -1 ) n = atoi ( buf );
}
}

int main ( )
{
get_interface ( );
int sock = init_socket ( );

pthread_t pt;

pthread_create ( &pt, NULL, reader, &sock );

struct sockaddr_in s;
s.sin_family = AF_INET;
inet_aton ( multi, &s.sin_addr );
s.sin_port = htons ( port );
char buf [ length ];
while ( 1 ) {
printf ( "> " );
fgets ( buf, length, stdin );
// write ( sock, buf, strlen ( buf ) );
sendto ( sock, buf, strlen ( buf ), 0, ( struct sockaddr * ) &s, sizeof s );
}

close ( sock );
}


因此,我正在等待您的帮助。

最佳答案

您需要在多播地址上使用bind。

struct sockaddr_in s;
s.sin_family = AF_INET;
inet_aton ( "224.0.0.2", &s.sin_addr );
s.sin_port = htons ( 12345 );
bind ( sock, ( struct sockaddr * ) &s, sizeof s );

关于c - 无法从多播组获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52052658/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com