2015-04-27 2 views
1

Я использую C# NetworkStream для чтения/записи на IP-адрес (а не на DNS-адрес).
Моя программа заменяет очень старую ассемблерную программу, которая была на мэйнфрейме. Теперь это в Windows.NetworkStream Read Extremely Slow

Я пишу/читаю менее 200 байт. Строки заканчиваются символом LineFeed, поэтому я использую StreamReader.Readline(), чтобы прочитать ответ после моего Stream.Write(). В IBM цикл записи/чтения занял 300ms.

Теперь, после каждых 2-го или 3-го чтения, для считывания требуется 15 секунд. Когда я читаю журнал отправителя, он отправляет данные менее чем за секунду. По некоторым причинам я получаю следующие 15 задержек.

Я не знаю, что происходит.

p.s. Одна странная вещь, которую я заметил, установив тайм-аут чтения потока на 4 секунды, он истекает около 4 секунд. Если я установил тайм-аут на 10 секунд или без таймаута, он истечет через 15 секунд.

TcpClient tcpc = null; 
NetworkStream stream = null; 
StreamReader sr = null; 

tcpc = new TcpClient(); 
tcpc.NoDelay = true; 
tcpc.ExclusiveAddressUse = false; 
tcpc.Connect("172.18.10.100", 4004); 

stream = tcpc.GetStream(); 
sr = new StreamReader(stream, Encoding.ASCII); 
sr.Peek(); 

string Message = null; 
Message = "IX3543543" + '\r'; 
stream.Write(Encoding.ASCII.GetBytes(Message), 0, Message.Length); 
string readmsg = null; 
for (int i = 0; i < 4; i++) 
    readmsg = sr.ReadLine(); 
+0

Вы пытаетесь прочитать данные с меньшим размером? Скажите 16 байт? Возможно, ваш мэйнфрейм поддерживает соединение, и из-за этого он становится задержкой. – VMAtm

+0

Я пишу на сервер терминалов, у которого есть сервер за ним. Моя программа заменяет программу мэйнфрейма. Я устанавливаю соединение и никогда не закрываю его или поток. Netstat -n -t 2 показывает, что соединение остается открытым. Соединение никогда не переходит в wait_state. Я тоже думаю, что это какая-то странная вещь Windows или антивирусная программа или что-то в этом роде. Тем не менее, я запускал свою программу на сервере и ноутбук с такими же результатами. Поэтому я в недоумении. – user965445

+0

Можете ли вы предоставить свой код? – VMAtm

ответ

0

Ваше сообщение остается открытым, поскольку ваш код никогда не освобождает ваши IDisposable ресурсов.

  1. Я думаю, что ваш код должен работать быстрее, если вы добавите конструкцию using.
  2. Также вы можете объединить декларацию и назначение, как это (это только стиль комментарий, основной проблемой является `IDisposable использование)
  3. И вы можете ReadToEnd ваше сообщение в ответ, и изучить его самостоятельно, вы после освобождения ресурсов ,

Так что ваш код может выглядеть примерно так:

string response = null; 
using(var tcpc = new TcpClient()) 
{ 
    tcpc.NoDelay = true; 
    tcpc.ExclusiveAddressUse = false; 
    tcpc.Connect("172.18.10.100", 4004); 

    using (var stream = tcpc.GetStream()) 
    using (var sr = new StreamReader(stream, Encoding.ASCII)) 
    { 
     sr.Peek(); 

     var Message = "IX3543543" + '\r'; 
     stream.Write(Encoding.ASCII.GetBytes(Message), 0, Message.Length); 
     response = sr.ReadToEnd(); 
    } 
} 

// examine message here 
var lines = response.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); 
+0

Это программа 7x24, поэтому я не хочу закрывать поток или соединение. Реальный код - несколько тысяч строк, потому что происходит запись и чтение базы данных. Таким образом, использование утверждений не является практическим. Я просто дал простой пример, чтобы проиллюстрировать проблему. – user965445

+0

Если вы не закрываете соединение, почему вы удивлены тем, что оно открыто? Лучший способ достичь производительности - это как можно скорее закрыть соединение и, при необходимости, открыть еще один. – VMAtm

+0

Я сделал трассировку сети. Я нашел, что в коде C# я посылаю. 15 секунд спустя он отображается в трассировке NetMonitor как отправленный. Я отключил Symantec Endpoint Protection, без изменений. – user965445

Смежные вопросы