NetworkStream.Read задержка .Net

У меня есть класс, который наследуется от TcpClient. В этом классе у меня есть метод обработки ответов. В этом методе, который я вызываю, я получаю NetworkStream с MyBase.GetStream и вызываю для него Read.

Это отлично работает, за исключением того, что первый вызов для чтения блоков слишком длинный. И под слишком длинным я подразумеваю, что сокет получил много данных, но не будет их читать, пока не будет достигнут какой-то произвольный предел. Я вижу, что он получил много данных с помощью анализатора пакетов WireShark.

Я установил буфер приема на небольшие суммы и очень маленькие суммы (например, всего на несколько байтов) безрезультатно. Я сделал то же самое с массивом байтов буфера, который я передаю методу чтения, и он все еще задерживается.

Или, говоря иначе. Я скачиваю 600к. Загрузка занимает 5 секунд (при скорости подключения к серверу чуть более 100 тыс./сек., что имеет смысл). Первоначальный вызов чтения занимает 2-3 секунды и сообщает мне, что доступно только 256 байт (256 - это буфер приема и размер массива, в который я читаю). Затем волшебным образом остальные несколько сотен тысяч байтов могут быть прочитаны кусками по 256 байт всего за несколько тактов процесса каждый. Используя анализатор пакетов, я знаю, что за эти начальные 2-3 секунды сокет получил гораздо больше, чем просто 256 байт. Мое соединение не было 0,25k/sec в течение 3 секунд, а затем 400k в течение 2 секунд.

Как получить байты из сокета по мере их поступления?


person Gilbes    schedule 27.12.2009    source источник
comment
Что еще находится между вашим сетевым адаптером и вашим приложением? Отключите брандмауэр, антивирусный сканер, CRL, прокси, посмотрите, что произойдет.   -  person Hans Passant    schedule 27.12.2009
comment
nobugz, это была проблема. Это было мое антивирусное приложение. Он должен буферизовать определенное количество байтов, чтобы просмотреть их, прежде чем передать их в буфер сокета. Это имеет смысл, потому что я использую хорошо известный порт, который он будет сканировать. Не могу поверить, что я не думал об этом. Вы должны опубликовать это как ответ, чтобы я мог отметить его как хороший.   -  person Gilbes    schedule 28.12.2009


Ответы (2)


У меня была аналогичная проблема при написании сетевой библиотеки C# с открытым исходным кодом. Попробуйте установить:

tcpClient.NoDelay = true;
tcpClient.Client.NoDelay = true;

Это отключает алгоритм Nagle, работающий по умолчанию. Это преднамеренно вызывает всевозможные случайные задержки при отправке и получении очень небольших объемов данных.

person MarcF    schedule 18.12.2011

Я сталкивался с этим несколько раз и раньше, и, похоже, это связано с проверкой настроек Internet Explorer машины (настройки прокси-сервера/настройки локальной сети и т. д. и т. д.), что вызывало задержку в 2-3 секунды.

Классы внутри пространства имен System.Net (например, WebClient, HttpWebRequest), по-видимому, делают это автоматически при первом запросе.

Вы можете попробовать отключить или изменить настройки прокси-сервера IE / настройки локальной сети, особенно параметр автоматического определения настроек, это может помочь.

Если это не поможет, взгляните на эту статью: Таинственная задержка при первом использовании HttpWebRequest.GetRequestStream. Это не совсем TcpClient, но я думаю, что это та же проблема.

Надеюсь это поможет.

person chakrit    schedule 27.12.2009
comment
Это была хорошая идея. Но я отключил определение прокси, в IE и в app.config, и на задержку это не повлияло. - person Gilbes; 28.12.2009