Используя Winsock, C ++, я отправляю и получаю данные с помощью send () / recv () , TCP-соединение.Я хочу быть уверен, что данные были доставлены другой стороне, и задаюсь вопросом, не рекомендуется ли отправить обратно какое-либо подтверждающее сообщение после (если) получения данных с помощью recv .
ЗдесьЕсть две возможности, и, пожалуйста, посоветуйте, куда идти:
Если send возвращает размер переданного буфера, предположим, что данные были доставлены по крайней мере до recv функция на другой стороне провода.Когда я говорю «по крайней мере», я имею в виду, даже если recv терпит неудачу там (например, из-за недостатка буфера и т. Д.), Мне все равно, я просто хочу быть уверен, что сделалсерверная часть работы правильно - я отправил данные полностью (т.е. данные дошли до другой машины).
Использовать дополнительное подтверждение: после получения данных с помощью recv отправить назад некоторый идентификатор принятого пакета (часть заголовка каждой отправленной информации), сигнализируя об успешной операции приема этого пакета.Если я не получаю такого «сообщения подтверждения» через некоторое время, верните код ошибки из функции отправителя.
Второй ответ выглядит более безопасным, но я не хочу усложнятьпротокол передачи, если он избыточен.Также обратите внимание, что я говорю о TCP-соединении (которое само по себе безопаснее, чем UDP).
Существуют ли другие механизмы (может быть, некоторые другие API-интерфейсы? Может быть, WSARecv () / WSASend () работает по-другому?) Чтобы гарантировать, что данные были доставлены в функцию recv на другой стороне?
Если вы порекомендуете второй способ, не могли бы вы дать мне кодфрагмент, который позволяет мне использовать recv с таймаутом для получения подтверждения? recv является операцией блокировки, поэтому она будет зависать вечно, если предыдущая попытка отправки не удалась (другая сторона не была уведомлена).Есть ли простой способ использования recv с тайм-аутом (без создания отдельного потока каждый раз, который, вероятно, будет избыточным для каждой операции send ).
Такжеобъем данных, которые я передаю функции send , может быть довольно большим (несколько мегабайт), так как выбрать тайм-аут для «сообщения подтверждения»?Может быть, мне следует «разделить» большие буферы и использовать несколько send вызовов?Я думаю, что это будет довольно сложно, пожалуйста, совет!
РЕДАКТИРОВАТЬ: ОК, вы, люди, предлагаете, что стек TCP / IP будет обрабатывать его (т. Е. Ручное подтверждение не требуется), но это то, что я нашелна странице MSDN: «Успешное завершение функции send не означает, что данные были успешно доставлены и получены получателю. Эта функция только указывает на то, что данные были успешно отправлены».Поэтому, даже если механизм TCP имеет возможность обеспечить доставку данных, я не могу получить этот статус (успешно или нет) с помощью функции send () или любой другой функции Winsock, которую я знаю.Знаете ли вы какой-нибудь способ получения статуса из уровня TCP?Опять же - возвращаемого значения функции send () кажется недостаточно!
========================================================
РЕДАКТИРОВАТЬ 2: ОК, я думаю, мы согласны с тем, что, хотя протокол TCP учитывает обработку ошибок, когда что-то идет не так, функция Winsock send () не способна сообщать об ошибках ( просто потому, что он возвращается до начала фактической передачи данных сетевым драйвером). Итак, вот вопрос на миллион долларов: гарантирует ли функция Winsock send () по крайней мере, что другие пакеты не будут доставлены другой стороне, пока не будет текущий пакет? Другими словами, если отправка не удалась из-за сбоя в сети (но не сообщается send () call), а затем сбой сети будет исправлен до следующего вызова send () будет работать со следующей порцией данных, будет ли гарантировано, что предыдущий пакет (который не был обработан, но не сообщен send () ) будет доставлен до следующего пакета? Другими словами, есть ли вероятность того, что одна конкретная функция send () завершится сбоем "без вывода сообщений", так что последующие вызовы send () будут выполнены успешно, но первый пакет будет потерян? ОПЯТЬ - я говорю не на уровне TCP, я говорю на уровне Winsock API!