Почему WSASendMsg возвращает WSAEINVAL для сокета, возвращенного из accept()?

У меня есть серверное приложение Windows, которое делает

  • WSAStartup(), очевидно
  • listen() на TCP-порте X
  • accept() входящее соединение
  • ioctlsocket() переводит сокет в неблокирующий режим
  • попробуйте ответить с помощью WSASendMsg

Я получаю код ошибки WSAEINVAL, который предположительно означает: «Сокет не был связан с привязкой или сокет не был создан с флагом перекрытия».

В этом случае нет смысла вызывать bind(), так как сокет уже связан с локальным и удаленным адресами. И сокет определенно не был создан с флагом перекрытия.

Итак, какова настоящая причина, по которой я получаю сообщение об ошибке, избежавшее этой строки документации?


person Tim Lovell-Smith    schedule 05.12.2013    source источник


Ответы (1)


AFAICWO: Поскольку я использую accept() для прослушивания запроса на подключение к TCP-сокету, accept возвращает мне сокет, ориентированный на соединение. Поэтому я должен использовать WSASend() вместо WSASendMsg(). В документах MSDN есть этот лакомый кусочек, который в конечном итоге подсказал мне, где я ошибался:

Функцию WSASendMsg можно использовать только с дейтаграммами и необработанными сокетами.

Другими словами, WSASendMsg() предназначен ТОЛЬКО для использования в сценариях без установления соединения, таких как UDP, ICMP или любых других необработанных сокетах, где вы создаете свои собственные пакеты.

(Возможно, я мог бы также использовать WSASendTo() вместо этого:)

В сокете, ориентированном на соединение, параметры lpTo и iToLen игнорируются; в этом случае WSASendTo эквивалентен WSASend.

person Tim Lovell-Smith    schedule 05.12.2013
comment
Формулировка MSDN кажется небрежной. В нем должно быть написано «датаграмма сокеты или необработанные сокеты». - person user207421; 06.12.2013
comment
Большое спасибо за это, это спасло меня от разрыва волос. Однако кое-что поясню: в документации в самом верху сказано, что функция WSASendMsg отправляет данные и дополнительную управляющую информацию из подключенных и неподключенных сокетов.? Подключено ли здесь со ссылкой на необработанные сокеты? Потому что я полностью подумал, что это означает, что соединение означает, что вы можете использовать его в сокетах, ориентированных на соединение... - person user541686; 17.03.2020
comment
@ user541686 добро пожаловать! Под подключенным я просто имел в виду, что я принял запрос на TCP-соединение, то есть это соединение с потоковым сокетом. Позвольте мне обновить свой ответ, чтобы уточнить... - person Tim Lovell-Smith; 19.03.2020