Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Сети > Socket Windows recvfrom не принимает данные |
Автор: wondertalik 17.5.2012, 16:13 | ||
Портирую код tracerudp с линукс под виндоус. По сути это упрощенная утилита traceroute. Создаются два сокета, один для отправки udp пакета, второй для получения icmp. Пакет отправляется на указанный узел, узел отвечает icmp сообщением. А принять это сообщение не могу. recvfrom в packet_ok возвращает -1. Где моя ошибка. Кто может подсказать? Использую visual studio 2010.
|
Автор: feodorv 17.5.2012, 17:26 | ||
Добавлено @ 17:34 WSAGetLastError вызывали? Отправка/получение данных по сырым сокетам в Виндах возможна только из под администратора. И то говорят, что в седьмых виндах и это зарубили (сам я не пробовал)... |
Автор: wondertalik 17.5.2012, 18:55 | ||
возвращает -2, код 10022(WSAEINVAL) - http://msdn.microsoft.com/en-us/library/windows/desktop/ms740120(v=vs.85).aspx |
Автор: feodorv 17.5.2012, 22:09 | ||
-1??? Не знаю точно, в чём тут дело, но, судя по всему, не нравится сокет. Сокет нужно править с помощью WSAIoctl( ... SIO_RCVALL ... ) (что не так просто, так как требует привязки сырого сокета к интерфейсу). Кроме того, в приведённом коде select проверяется на возвращаемое значение SOCKET_ERROR, а на 0 не проверяется (для существующего кода без правки сокета select всегда будет возвращать 0 - ICMP пакетов нет)))). BSD-сокеты хороши в Юниксе, в Виндах лучше пользоваться родным WinSock API и неблокируемыми сокетами. И вот это работает:
|
Автор: wondertalik 17.5.2012, 23:47 | ||||
Может я чего-то не понимаю?
recvfrom возвращает -1 (n). |
Автор: wondertalik 18.5.2012, 01:22 | ||||||
Таймаут 1с. В течении 2 сек возвращается :
Где же подвох? Уже смотрел и сюда: http://msdn.microsoft.com/en-us/library/windows/desktop/ms742219(v=vs.85).aspx
вынес в main. |
Автор: feodorv 18.5.2012, 12:36 | ||||
WSAWaitForMultipleEvents просто завершается с WSA_WAIT_TIMEOUT (код ошибки при этом наследуется, то есть не правится). Лучше так:
Вот не знаю ![]()
|
Автор: wondertalik 18.5.2012, 14:53 | ||
А почему первый параметр 1, а не сокет rawsc? |
Автор: feodorv 18.5.2012, 15:32 |
Потому что первый параметр - число событий, которых мы ожидаем. В явном виде сокета здесь нет, но есть событие, ассоциированное с сокетом ![]() |
Автор: wondertalik 18.5.2012, 16:21 | ||||
Я благодарен Вам за помощь. Очень помогаете. Надеюсь и дальше сможете мне помочь, дабы добить до конца тему. И так, благодаря ВАм, пакеты icmp успешно принимаются. Вот код который получился на данный момент:
Теперь касательно разбора пакета. Допустим я хочу вывести протокол с айпи заголовка hip
Выводит 168, а должен 17(IPPROTO_UDP) . icmp->icmp_type, icmp->icmp_code выводятся с верными значениями. Причем, снифер WireShark, показывает, что протокол UDP(17). |
Автор: feodorv 18.5.2012, 21:12 | ||||
Где Вы взяли такое описание IP-заголовка??? Должно быть:
Вообще, для начала было бы неплохо контролировать то, что пришло по сокету:
И уже тут смотреть, 17 там или нет ![]() |
Автор: wondertalik 19.5.2012, 01:59 | ||||
[QUOTE=feodorv,18.5.2012, 21:12]
Действительно не углядел. ![]()
feodorv, огромное спасибо Вам за помощь. С такими успехами у меня все меньше желания прогить под Виндоус. Быть может я и не прав))). |
Автор: feodorv 19.5.2012, 04:20 |
Это вопрос привычки))) И Вы ещё сервисов не писали))) |
Автор: wondertalik 23.5.2012, 19:15 | ||
Код выше компилируется в визуал студио 2010 в режиме Debug. В release упорно не хочет. Выдает варнинги и ероры:
Как быть? |
Автор: feodorv 23.5.2012, 20:07 | ||||
Исправлять ![]() Прямо идти по каждому замечанию, разбираться в чём дело и... исправлять ![]() Например:
Перенос кода из одного места в другой требует некоторой правки. СтОит отказаться от переменной success (249 строчка) и вообще от всего цикла do...while. Буфер data (который ранее использовался в recvfrom) заменён на recvbuf и более не используется. Зачем тогда его объявление? Вот компилятор и недоумевает (а вдруг Вам он нужен был, а Вы где-то ошиблись и вместо него пользуете не то, что нужно). То же с sockAddr. Кстати, как у Вас со знаем английского языка? По-хорошему, даже варнингов не должно быть. Если они возникают, то это причина для разбора полётов (кроме шуток). Но, конечно, внимание программиста притягивают в первую очередь ошибки компиляции)))
Гм. В приведённом коде не нашёл тела функции timeGetTime... Видимо, не один я... Как это всё могло компилиться в режиме Debug, разобраться тоже стОит))) |