Не получается обратный вызов данных в сокете iOS UDP

Я пытаюсь настроить UDP-сокет на iOS для прослушивания дейтаграмм, поступающих через многоадресный сокет:

#import <CoreFoundation/CoreFoundation.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

void getSocketDataCallBack (CFSocketRef cfSocketRef, CFSocketCallBackType cbType, CFDataRef address, const void *data, void *info) {
    if (cbType == kCFSocketDataCallBack) {
        cout << "o";
    } else {
        cout << "x";
    }
}


void main () {
    CFSocketError cfErr;
    CFSocketContext udpSocketContext = {0, NULL, NULL, NULL, NULL};
    udpSocketContext.info = &cbData;
    CFSocketRef udpSocketRef = CFSocketCreate(kCFAllocatorDefault,
                                              PF_INET,
                                              SOCK_DGRAM,
                                              IPPROTO_UDP,
                                              kCFSocketDataCallBack,
                                              &getSocketDataCallBack,
                                              &udpSocketContext);
    if ( udpSocketRef == NULL) {
        cout << "CFSocketCreate failed\n";
    } else {
        cout << "UDP socket created\n";

        CFRunLoopSourceRef source = CFSocketCreateRunLoopSource( kCFAllocatorDefault, udpSocketRef, 0 );
        CFRunLoopAddSource( CFRunLoopGetMain(), source, kCFRunLoopCommonModes );

        struct sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));
        addr.sin_len = sizeof(addr);
        addr.sin_family = AF_INET;
        addr.sin_port = htons(MC_PORT);       //4194
        inet_aton(MC_ADDR, &addr.sin_addr);   //239.0.123.45

        //Tell socket to listen on this address
        CFDataRef cfDataRef = CFDataCreate(NULL, (const UInt8 *)&addr, sizeof(addr));
        cfErr = CFSocketSetAddress(udpSocketRef, cfDataRef);
    }
}

Все вызовы сокетов завершаются успешно, но я не получаю никаких обратных вызовов (я посылаю UDP-дейтаграммы на адрес MC из отдельного приложения macOS).

Что я делаю неправильно?

Спасибо за любую помощь! Приветствия.

1 ответ

Решение

Проблема заключается в том, что CFSocket сам по себе не позволяет получать дейтаграммы, отправленные на адрес многоадресной рассылки IPv4 (или IPv6). Но не все безнадежно!

На https://justanapplication.wordpress.com/category/posix/posix-system-calls/posix-socket/ я обнаружил следующее: "К счастью, функция CFSocketCreateWithNative может превратить теоретический сокет POSIX в теоретический CFSocket". Автор этого, Саймон Льюис, также говорит, что это на самом деле тоже работает, "по крайней мере, на iPad под управлением iOS 7.0.4", и он достаточно хорош, чтобы предоставить некоторый код, чтобы опробовать его. Удачи!

Другие вопросы по тегам