Соединение клиента TCP

Я не знаком с log4net или журналом. DebugFormat (...).

, Но стоимость входа находится действительно в двух областях.

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

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

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

, Например, в log4j, это было общей идиомой:

log.debug("Runtime error. Order #" + order.getOrderNo() + " is not posted.");

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

log.debug("Something wrong with this list: " + longListOfData);

, Который мог создать большую и дорогую строковую переменную, которая, если бы уровень журнала не был установлен для ОТЛАДКИ, была бы просто потрачена впустую.

защита:

if (log.isDebug()) {
    log.debug(...);
}

Устраняют ту проблему, так как вызов isDebug является дешевым, особенно по сравнению с фактическим созданием аргумента.

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

log.debug("Runtime error. Order # {0} is not posted.", order.getOrderNo());

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

Теперь, журнал. DebugFormat может сделать подобную вещь, которую я не знаю.

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

7
задан jp2code 10 August 2009 в 19:47
поделиться

3 ответа

Перед отправляемым содержимым следует указать длину этого содержимого. Ваш цикл предполагает, что все данные отправляются до выполнения цикла, тогда как на самом деле ваш цикл выполняется по мере отправки данных. Бывают моменты, когда в проводе нет ожидающих данных, поэтому цикл завершается; тем временем контент все еще отправляется по сети. Вот почему ваш цикл выполняется только один раз.

6
ответ дан 7 December 2019 в 05:26
поделиться

Если я правильно прочитал ваш код, вы в основном получили (извините за c-стиль - я плохо разбираюсь в C #:

do
{
  socket = accept();
  read(socket, buffer);
}while(not_done);

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

do
{
  socket = accept();
  do { read(socket, buffer); not_done_reading=...; } while (not_done_reading);
}while(not_done);

Если вы хотите читать несколько загрузок одновременно, вам понадобится что-то больше похоже:

do
{
  socket = accept();
  if( !fork() )
  {
    do { read(socket, buffer); not_done_reading=...; } while (not_done_reading);
  }
}while(not_done);
1
ответ дан 7 December 2019 в 05:26
поделиться

Ваш пример telnet несколько противоречит поведению кода, который вы описываете - если вы когда-либо сможете получить что-либо на сервере, "telnet " должен получить вы быстро перейдете на пустой экран (на компьютере с Windows в командной строке CMD). Итак, это первая странная вещь - лучше всего отлаживать с помощью wirehark, хотя .

Что касается кода, я думаю, что это может быть проблема с этой внутренней строкой на сервере:

... пока ((0

Вы говорите, что хотите выполнить цикл, пока вы смогли что-то прочитать и пока есть некоторые данные.

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

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

Примечание:

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

(Отказ от ответственности: я не очень много писал на C #, поэтому мог ошибиться в интерпретации метода "DataAvailable ()", возьмите этот FWIW).

Изменить: вероятно, мой ответ выше должен быть исправлено в соответствии с вашим протоколом - то есть вам нужно сначала прочитать длину файла,

1
ответ дан 7 December 2019 в 05:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: