.Net C # TcpClient / Socket HTTP Client Производительность / Эффективность - PullRequest
2 голосов
/ 01 декабря 2009

Я пишу HTTP-клиент, используя .Net TcpClient / Sockets.

Пока клиент обрабатывает ответы Content-Length и chunked, перебирая ответ NetworkStream (после записи запроса GET в TcpClient), анализируя заголовки и извлекая соответствующие байты тела сообщения / chunked байты. Для этого используется метод NetworkStream ReadByte.

Все это прекрасно работает, но производительность является ключевым аспектом приложения, поэтому я хотел бы сделать его максимально быстрым и эффективным.

Первоначально это будет включать в себя обмен ReadByte для чтения для тела сообщения (на основе Content-Length) или извлечение байта тела фрагментированного сообщения в буфер соответствующего размера с использованием ReadByte во всех других областях (таких как чтение заголовков, размеров блоков и т. Д.). ).

Мне интересно узнать мысли о лучших / разных способах сделать это для достижения оптимальной производительности? Очевидно, что основная проблема с HTTP заключается в отсутствии информации о длине потока ответа, если он не анализируется при его получении.

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

Большое спасибо,

Chris

1 Ответ

1 голос
/ 01 декабря 2009

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

Если вы хотите прочитать важную часть информации в начале потока, прочитайте достаточно потока, чтобы увидеть это. (Другими словами, вам не нужно заполнять буфер при первом проходе, если вы не хотите.)

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

Редактировать

В ответ на вопрос с комментарием, если у вас есть одно соединение, которое вы пытаетесь использовать повторно для нескольких запросов, вы должны создать поток, который будет читать его снова и снова. Когда он находит данные, он использует это событие, чтобы вытолкнуть их для обработки основной частью вашей программы. У меня нет удобного примера, но вы сможете найти несколько с помощью нескольких запросов bing или google.

...