Какие гарантии указывает спецификация на количество переданных байтов при использовании SendAsync с помощью SocketAsyncEventArgs.BufferList
?
Для начала, событие может быть поднято при ошибках, и в этом случае вы можете предположить, что не все байты были переданы. Для этого вам нужно протестировать SocketAsyncEventArgs.SocketError для SocketError.Success. Кроме того, если вы ссылаетесь на «спецификацию», я предполагаю, что вы имеете в виду документацию Microsoft Windows Sockets (поскольку вы ссылаетесь на это для SendAsync и других описаний).
Для того, чтобы узнать, что в документации указано или подразумевается для количества переданных байтов при вызове события Completed в случае успеха, мы должны сделать несколько шагов. Первый шаг - посмотреть, использует ли SendAsync перекрывающиеся ввода-вывода. На этот вопрос ответят в документации Overlapped Input/Output. Реализация этого механизма является обязательной для основных поставщиков транспорта и, следовательно, является единственным перекрывающимся механизмом ввода-вывода, который гарантированно будет доступен для Windows Sockets. Таким образом, SendAsync гарантированно использует сокет с атрибутом WSA_FLAG_OVERLAPPED.
Обратите внимание, что проверка SendAsync reference implementation показывает, что SendAsync действительно использует WSASend с перекрывающимися вводами-выводами, но это всего лишь наблюдение.
Второй шаг - определить, какие перекрывающиеся ввода-вывода сообщают нам о передаче завершенного события, связанного с количеством переданных байтов. Эта ситуация описана в нескольких местах, например, на этой странице Overlapped I/I and Event Objects: «индикация будет указана при потреблении буферов отправки». В разделе замечаний для функции [WSASend] приводится более подробная информация: «Будет отображаться индикация завершения, вызывая завершение процедуры или установки объекта события, когда буфер (ы) были использованы транспортом», ,
Это все еще оставляет место для точной интерпретации этой фразы.В основном это говорит о том, что данные были приняты и подтверждены базовым транспортным механизмом из области сокета. Это не обязательно означает, что он достиг уровня удаленного протокола конечной точки, это будет зависеть от протокола связи. Для TCP-потокового сокета я бы сделал вывод, что он указывает, что данные достигли удаленной конечной точки.
Вывод состоит в том, что документация гарантирует (для ситуации без ошибок), что завершенное событие SendAsync возникает только в момент, когда все байты были переданы.
Я думаю, что вопрос будет следующим: «Можно ли вызывать обработчик' SocketAsyncEventArgs.Completed' без ошибки сокета и 'e.BytesTransferred! = Length'?" Из того, что я могу собрать в .NET Framework, невозможно: http://stackoverflow.com/questions/28675811/when-i-call-wsasend-will-all-the-data-be-sent и http: // stackoverflow .com/questions/14347708/call-wsasend-in-complete-port – jorgebg
Можете ли вы предоставить код для тестирования? –
@DieterMeemken Что вам нужно для тестирования, чтобы ответить _Что гарантирует ли спецификация make_? Как я уже упоминал, я использую 'SendAsync' с' SocketAsyncEventArgs' с набором 'BufferList'. –