2013-08-30 2 views
0

У меня есть некоторые проблемы в Windows 8 с использованием recvfrom. У меня есть сокет, привязанный к INADDR_ANY (0.0.0.0), и я хотел бы получить некоторые пакеты на нем.Ничего не получено от recvfrom на окнах

Проблема в том, что я вижу эти пакеты в Wireshark, но recvfrom никогда не сообщает мне, что полученный размер больше 0. Я пробовал доставлять сокет до 127.0.0.1 или даже на локальный адрес IPv4, я никогда получить что-нибудь. Используемый порт - 7321 (локально)

Я использую библиотеку ENet для создания сокета, а затем я использовал этот сокет в recvfrom. Вот код, который никогда не возвращает ожидаемые пакеты.

uint8_t* buffer; // max size needed normally (only used for stun) 
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048)); 
memset(buffer, 0, 2048); 

socklen_t from_len; 
struct sockaddr addr; 

from_len = sizeof(addr); 
int len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, &addr, &from_len); //m_host is of type ENetHost, the socket in it is a file descriptor like standard sockets 

Как я уже сказал, это немного странно, как Wireshark показывает мне пакеты (которые STUN ответы, если вы хотите знать).

Может кто-нибудь помочь мне узнать, чего не хватает, что может вызвать эту проблему?

+0

У меня была аналогичная проблема, недавно, когда Wireshark сообщила об этом пакете, и приложение прослушивало, но пакет не получил. Оказывается, это была таблица маршрутизации. Может, это и ваша проблема? (Это было на Linux, поэтому я не знаю, как проверить или исправить его в Windows) –

ответ

0

Ваша addr переменная объявлена ​​как sockaddr. Он должен быть объявлен как sockaddr_in (работает только с IPv4) или SOCKADDR_STORAGE (работает как с IPv4, так и с IPv6), а затем выводит его на sockaddr* при передаче его на recvfrom().

Кроме того, вы говорите, что recvfrom() не возвращает> = 0. Так что же это действительно возвращается? Если он возвращает 0, то был получен пакет длиной 0 (невозможно для TCP, но возможно для UDP). Если он возвращает -1 (aka SOCKET_ERROR), тогда произошла ошибка, поэтому используйте WSAGetLastError(), чтобы узнать, что это за ошибка.

+0

Привет, спасибо большое за помощь: first: использование sockarrd_in сначала не помогает, может быть потому, что функция recvfrom ждет sockaddr * в качестве пятого параметра, а не sockaddr_in * second: always return -1. Я попытаюсь выполнить WSAGHetLastError() и расскажу вам, что результат. – hilnius

+0

У меня есть ошибка: «немедленная операция блокировки сокета не может быть завершена» – hilnius

+0

Во-первых, 'recvfrom()' не хочет 'sockaddr', он хочет, чтобы все соответствовало базовому типу сокета -' sockaddr_in' для IPv4, ' sockaddr_in6' для IPv6 и т. д. Если он действительно хотел, чтобы 'sockaddr', чем шестой параметр, не существовал, но он существует, потому что пятый параметр на самом деле является переменной длиной. Во-вторых, 'WSAGetLastError()' дает код ошибки, а не строку. Сообщение об ошибке, которое вы указали, предполагает, что вы получаете код WSAEWOULDBLOCK (10035) как код ошибки, что совершенно нормально, если вы используете неблокирующий сокет, и в данный момент нет данных для чтения. –

0

я могу думать о 2 возможных причин у вас возникли проблемы:

1) Вы не могли бы иметь порт правильно на вашем SendTo & recvfrom гнездо. Скажем, вы отправляете пакеты на порт 6000, но ваш recvfrom прослушивает порт 6001 или что-то в этом роде. Просто дважды проверьте, что обе программы используют один и тот же порт.

2) Брандмауэр Windows. Я буду запускать программу как администратор, чтобы быть в безопасности, но также убедитесь, что вы разрешаете вашей программе через брандмауэр Windows взаимодействовать с использованием частных или общедоступных сетей.

+0

Я попытался отключить все брандмауэры (антивирус + окна) и проверенные порты. Сокет явно прослушивает 0.0.0.0:7321, а wirehark сообщает мне, что пакет поступает на порт 7321, IP-адрес назначения - 192.168.0.11 (мой локальный IP-адрес). – hilnius

Смежные вопросы