Получение групповой рассылки Winsock UDP с DirectShow

#c #directshow #winsock

#c #directshow #winsock

Вопрос:

В настоящее время я пытаюсь получать многоадресные UDP-пакеты внутри фильтра directshow в его собственном std:: thread. Я создал небольшую функцию, которая успешно принимает пакеты при автономном запуске в качестве консольного приложения. Однако вставить этот код в любое место фильтра directshow не удается. (В настоящее время в качестве примера отправной точки используется pushsource) В частности, recvfrom возвращает -1, а WSAGetLastError() возвращает 10060. (протестировано путем размещения фильтра на графике с помощью graphstudio)

Это мой кодовый блок, который создает сокет и пытается прочитать из него данные, которые запускаются с помощью std::thread.

 char* multicast_ip = "239.1.2.3";
unsigned short multicast_port = atoi("3000");
SOCKADDR_IN multicast_addr;
WSADATA wsaData;
int hr;
BOOL bOptVal = TRUE;
ip_mreq mreq;
int max_length = 16;

WSAStartup(MAKEWORD(2,0), amp;wsaData);

SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

// construct bind structure
memset(amp;multicast_addr, 0, sizeof(multicast_addr));
multicast_addr.sin_family = AF_INET;
multicast_addr.sin_addr.s_addr = htonl(INADDR_ANY);
multicast_addr.sin_port = htons(multicast_port);

hr = bind(sock, (struct sockaddr *) amp;multicast_addr, sizeof(multicast_addr));

/* Specify the multicast group */
mreq.imr_multiaddr.s_addr = inet_addr(multicast_ip);
/* Accept multicast from any interface */
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
/* Join the multicast address */
hr = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *) amp;mreq, sizeof(mreq));

int optval = 8;
hr = setsockopt(sock,IPPROTO_IP,IP_MULTICAST_TTL, (char*)amp;optval,sizeof(int));

hr = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)amp;bOptVal, sizeof(bOptVal));

int timeout = 1000; // 1 sec
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *) amp;timeout, sizeof(timeout));

while (true)
{
    char buffer[4096] = { 0 };

    int i = recvfrom(sock, buffer, 4096, 0, NULL, 0);

    int wut = WSAGetLastError();
}
WSACleanup();
  

У кого-нибудь есть какие-либо идеи о том, почему это будет работать как отдельное приложение, но когда этот код помещается где-либо внутри фильтра, он не получает данные? [Код, который фактически отправлял бы данные из буфера, подлежащего обработке, опущен для краткости, поскольку recvfrom не возвращает никаких данных]

Комментарии:

1. Я полагаю, важно, как именно вы вставляете этот код в фильтр: сам код в порядке (он работает автономно), база DirectShow не использует сокеты, а затем способ, которым вы объединяете их вместе — вы этого не показываете.

2. Первоначально я просто собрал весь этот код вместе в функции foo() и запустил std::thread, указывающий на foo в конструкторе моего вывода pin. Я тестировал это в различных других местах, таких как конструктор фильтра и CreateInstance (), но оба привели к одинаковому поведению -1, возвращаемому recvfrom, и сообщению winsock об ошибке 10060. Это происходит в новом примере проекта pushsource. Есть ли какое-то специальное место, где я должен создавать поток?