Ответ 1
Какие гарантии указывает спецификация количества байтов, переданных при использовании SendAsync с SocketAsyncEventArgs.BufferList
?
Для начала, событие может быть поднято на ошибках, и в этом случае вы можете предположить, что не все байты были перенесены. Для этого вам нужно протестировать SocketAsyncEventArgs.SocketError для SocketError.Success. Кроме того, если вы ссылаетесь на "спецификацию", я предполагаю, что вы имеете в виду документацию Microsoft Windows Sockets (поскольку вы ссылаетесь на это для SendAsync и других описаний).
Для того, чтобы понять, что в документации сказано или подразумевается количество переданных байтов при вызове события Completed в случае успеха, мы должны сделать несколько шагов. Первый шаг - посмотреть, использует ли SendAsync перекрывающиеся ввода-вывода. Ответ на этот вопрос содержится в документации Overlapped Input/Output. Реализация этого механизма является обязательной для основных поставщиков транспорта и, следовательно, является единственным перекрывающимся механизмом ввода-вывода, который гарантированно будет доступен для Windows Sockets. Таким образом, SendAsync гарантированно использует сокет с атрибутом WSA_FLAG_OVERLAPPED.
Обратите внимание, что проверка ссылочной реализации SendAsync показывает, что SendAsync действительно использует WSASend с перекрывающимся вводом-выводом, но это просто наблюдение.
Второй шаг - определить, какие перекрывающиеся операции ввода-вывода сообщают нам о передаче завершенного события, связанного с количеством переданных байтов. Эта ситуация описана в нескольких местах, например, на этой странице Overlapped I/I и Объекты событий: индикация будет отображаться, когда буферы отправки имеют потребляется. Более подробная информация приведена в разделе замечаний для функции [WSASend]: "Появится индикация завершения, вызывающая завершение процедуры или установки объекта события, когда буфер были потреблены транспортом.
Это все еще оставляет место для точной интерпретации этой фразы. В основном это говорит о том, что данные были приняты и подтверждены базовым транспортным механизмом из области сокета. Это не обязательно означает, что он достиг уровня удаленного протокола конечной точки, это будет зависеть от протокола связи. Для TCP потокового сокета я бы сделал вывод, что он указывает, что данные достигнут удаленной конечной точки.
Вывод состоит в том, что документация гарантирует (для ситуации без ошибок), что завершенное событие SendAsync возникает только в момент, когда все байты были переданы.