Как ведет себя метод NetworkStream.Write(), если я отправляю данные через NetworkStream TcpClient и TcpClient.SendBufferSize
меньше данных?
документация MSDN для SendBufferSize говорит
Если сетевой буфер меньше, чем объем данных, которые вы предоставляете методу Write, несколько операций сетевой отправки будут выполняться для каждого вызова, который вы делаете для метода Write. Вы можете добиться большей пропускной способности данных, убедившись, что размер сетевого буфера не меньше размера буфера вашего приложения.
Поэтому я знаю, что данные будут отправлены в несколько операций, и принимающий TCP-стек должен прозрачно собрать их в один непрерывный поток.
Но что именно происходит в моей программе за это время?
Если в SendBuffer достаточно места, TcpClient.GetStream().Write()
вообще не будет блокироваться и вернется немедленно и так будет NetworkStream.Flush().
Если я установлю TcpClient.SendBufferSize
на значение меньше, чем данные, Write()
будет блокировать до тех пор, пока
- либо первая часть данных была получена и подтверждена ACK,
- или
TcpClient.SendTimeout
истек?
Или это работает как-то иначе? Действительно ли он ждет TCP ACK?
Есть ли какие-либо другие недостатки, помимо более высоких накладных расходов для такого меньшего размера буфера? Есть ли проблемы с изменением SendBufferSize на лету?
Пример:
byte[] data = new byte[20] // 20 byte data
tcpClient.SendBufferSize= 10; // 10 byte buffer
tcpClient.SendTimeout = 1000; // 1s timeout
tcpClient.GetStream().Write(data,0,20);
// will this block until the first 10 bytes have been full transmitted?
// does it block until a TCP ACK has been received? or something else?
// will it throw if the first 10 bytes have not been received in 1 second?
tcpClient.GetStream().Flush(); // would this make any difference?
Моя цель в основном состоит в том, чтобы лучше понять внутреннее устройство сети.
Кроме того, мне было интересно, можно ли этим злоупотребить, чтобы быстрее реагировать на сбой сети. Если данные отправляются нечасто, и каждый пакет данных достаточно мал, чтобы быть переданным за один раз, и в заданном протоколе сообщений нет сообщений о приеме, после сетевой ошибки может пройти много времени, пока не будет вызван следующий Write(). ; так долго, пока не будет выброшено исключение.
Если SentBuffer очень мал, будет ли ошибка обнаружена быстрее, если только она не произойдет в конце данных?
Могу ли я злоупотреблять этим, чтобы измерить время, необходимое для передачи и подтверждения одного пакета?