У создания TcpClient много накладных расходов? - PullRequest
4 голосов
/ 19 февраля 2010

Я пытался отправлять / получать данные с помощью TcpClient. Я провел два эксперимента и нашел что-то интересное.

Я установил TcpListener на сервере в Японии и TcpClient в Великобритании. Я продолжал посылать 500 байтов в TcpListener и когда TcpListener отправляет 10KB обратно в TcpClient. Я держал этот цикл отправки / получения 500 раз в каждом эксперименте.

Эксперимент 1:

В каждом цикле отправки / получения я создаю новый TcpClient (время отсчитывается непосредственно перед созданием) и отправляю / получаю

Эксперимент 2:

Для всех циклов у меня есть только один TcpClient, и он поддерживает соединение с TcpListener и выполняет отправку / получение 500 раз.

Результат:

Среднее значение затрат времени на один цикл:

E1: 1,8 секунды, E2: 0,49 секунды.

Я весьма удивлен этим результатом. Таким образом, поддержание связи для постоянной отправки / получения может сэкономить много времени ??? почти 2/3 времени.

Это правда ???

Спасибо

==== новый ====

@ Jon Skeet, @dbemerlin, спасибо за ответ. Я догадался, что рукопожатия Tcp требуют некоторого времени.

Итак, я выполнил эксперимент 3.

Я устанавливаю HttpListener в качестве сервера и использую WebClient для отправки / получения, размеры данных точно такие же. И каждый раз я использовал новый WebClient для отправки / получения между Великобританией и Японией.

Результат равен 0,86 (в среднем от цикла 500 раз, т.е. отправка / получение).

Я полагаю, что сами WebClient / HttpLisener являются Tcp, верно? Как они могут быть быстрее, чем необработанные TcpClient / TcpListener в моих экспериментах ??

Еще раз спасибо

Ответы [ 2 ]

6 голосов
/ 19 февраля 2010

Это не особенно удивительно, но это не стоимость создания объекта - это стоимость установки TCP-соединения, рукопожатий и т. Д.

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

Эффективный сценарий: вы набираете номер, они отвечают, вы говорите, они отвечают, вы говорите, они отвечают и т. Д.

Неэффективный сценарий: вы набираете номер, они отвечают, вы говорите, они отвечают, вы кладете трубку. Затем вы сразу же набираете номер снова, они отвечают, вы говорите, отвечаете, вы вешаете трубку и т. Д.

Представь, что ты делаешь последнее в реальности! Вы бы очень быстро сошли с ума ...

EDIT: по умолчанию, WebClient оставляет висячее соединение открытым для веб-сервера. Если вы принудительно сбросите соединения (в основном отключите KeepAlive), вы снова увидите медленное поведение.

1 голос
/ 19 февраля 2010

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

Посылка отправляется из Великобритании в Японию, предположим, за 100 мс. Это означает, что для каждого tcpClient.Connect () требуется 300 мс без каких-либо отправленных данных. Обычная отправка и получение состоит из одной посылки, отправленной в пункт назначения, и еще одной посылки, общей суммой 200 мс. Отключение (если оно чистое) требует еще 100 мс.

Это приводит к 600 мсек для отправки сообщения, по сравнению с 200 мс, если вы сохраняете соединение, поскольку вы затем сохраните рукопожатие и завершение работы.

...