Пишу простой эхо TCP-сервер и клиента к нему на C#.
Решил провести некое нагрузочное тестирование.
Запускаю один экземпляр сервера и клиента. Клиент в цикле шлет сообщения, сервер ему отвечает.
Если в клиенте после каждой отправки вставить Thread.Sleep(10), то все отрабатывает без ошибок для 10000 сообщений.
Если убрать Sleep, то где-то на 3000 сообщении получаю ошибку на сервере при вызове NetworkStream.Write:
unable to write data to the transport connection an established connection was aborted
Вопрос: с чем это может быть связано? Баг в программе или некие естественные ограничения. Хотелось бы понять природу возникновения этой ошибки.
Спасибо.
Re: Помогите понять причину ошибки (unable to write data to the transport connec
Здравствуйте, breee breee, Вы писали:
BB>Привет.
BB>Пишу простой эхо TCP-сервер и клиента к нему на C#. BB>Решил провести некое нагрузочное тестирование. BB>Запускаю один экземпляр сервера и клиента. Клиент в цикле шлет сообщения, сервер ему отвечает.
BB>Если в клиенте после каждой отправки вставить Thread.Sleep(10), то все отрабатывает без ошибок для 10000 сообщений. BB>Если убрать Sleep, то где-то на 3000 сообщении получаю ошибку на сервере при вызове NetworkStream.Write:
BB>unable to write data to the transport connection an established connection was aborted
BB>Вопрос: с чем это может быть связано? Баг в программе или некие естественные ограничения. Хотелось бы понять природу возникновения этой ошибки.
Хотелось бы знать, как происходит отправка и чтение данных в клиенте? Сообщение отправить, сообщение прочесть? Или отправить 100 сообщений, читать ответы по мере поступления? Сервер когда читает, как определяет границы сообщений?
Re[2]: Помогите понять причину ошибки (unable to write data to the transport con
Здравствуйте, v_andal, Вы писали:
_>Хотелось бы знать, как происходит отправка и чтение данных в клиенте? Сообщение отправить, сообщение прочесть? Или отправить 100 сообщений, читать ответы по мере поступления?
У клиента есть два потока: в одном сообщения отправляются в цикле, в другом — читаются, тоже в цикле. Согласно документации NetworkStream — это допустимо.
_>Сервер когда читает, как определяет границы сообщений?
Все сообщения начинаются с фиксированной длины, затем идет переменное тело. Сервер сначала читает длину, затем само тело.
Re[3]: Помогите понять причину ошибки (unable to write data
Здравствуйте, breee breee, Вы писали:
BB>Здравствуйте, v_andal, Вы писали:
_>>Хотелось бы знать, как происходит отправка и чтение данных в клиенте? Сообщение отправить, сообщение прочесть? Или отправить 100 сообщений, читать ответы по мере поступления? BB>У клиента есть два потока: в одном сообщения отправляются в цикле, в другом — читаются, тоже в цикле. Согласно документации NetworkStream — это допустимо.
_>>Сервер когда читает, как определяет границы сообщений? BB>Все сообщения начинаются с фиксированной длины, затем идет переменное тело. Сервер сначала читает длину, затем само тело.
То есть у сервера только один поток? А сервер учитывает, что он может прочесть только кусок сообщения за раз? Потенциально, он и при записи может отправить только часть из отправляемых данных.
В принципе, если сообщения не очень большие, можно весь обмен каким-нибудь wireshark перехватить и посмотреть, что происходит на уровне сети. Если на этом уровне соединение не пропадает, то значит баг в библиотеке или программе. Если же соединение рубится на уровне сети, то значит клиент его почему-то закрывает.
Если бы дело было под никсами, то я бы порекомендовал подцепить strace и посмотреть на уровне системных вызовов. Есть ли подобная утилита для виндов, я не знаю.
Здравствуйте, breee breee, Вы писали:
BB>Если в клиенте после каждой отправки вставить Thread.Sleep(10), то все отрабатывает без ошибок для 10000 сообщений. BB>Если убрать Sleep, то где-то на 3000 сообщении получаю ошибку на сервере при вызове NetworkStream.Write:
BB>unable to write data to the transport connection an established connection was aborted
Почему-то есть стойкое ощущение, что сервер не успевает вычитывать запросы, поэтому в итоге решает проблему перхоти кардинально — через секир-башка.
Re: Помогите понять причину ошибки (unable to write data to the transport connec
Здравствуйте, v_andal, Вы писали:
_>>>Сервер когда читает, как определяет границы сообщений? BB>>Все сообщения начинаются с фиксированной длины, затем идет переменное тело. Сервер сначала читает длину, затем само тело.
_>То есть у сервера только один поток?
Для каждого клиента свой поток. Вернее, все сделано через async/await и таски, поэтому в конечном счете используется пул потоков. Но ошибку я получаю при тестировании с одним клиентом, поэтому в принципе можно считать, что поток один.
_>А сервер учитывает, что он может прочесть только кусок сообщения за раз? Потенциально, он и при записи может отправить только часть из отправляемых данных.
Да, это учитывается.
_>В принципе, если сообщения не очень большие, можно весь обмен каким-нибудь wireshark перехватить и посмотреть, что происходит на уровне сети. Если на этом уровне соединение не пропадает, то значит баг в библиотеке или программе.
Спасибо за попробую.
_>Если же соединение рубится на уровне сети, то значит клиент его почему-то закрывает.
Клиент тоже мой. Вроде никаких ошибок на его стороне не происходит.
Здравствуйте, Mr.Delphist, Вы писали:
BB>>unable to write data to the transport connection an established connection was aborted
MD>Почему-то есть стойкое ощущение, что сервер не успевает вычитывать запросы, поэтому в итоге решает проблему перхоти кардинально — через секир-башка.
А как бы убедиться, что действительно дело в этом?
Re[2]: Помогите понять причину ошибки (unable to write data
Здравствуйте, SkyDance, Вы писали:
BB>>Вопрос: с чем это может быть связано? Баг в программе или некие естественные ограничения. Хотелось бы понять природу возникновения этой ошибки.
SD>Баг, конечно. Выложите код, посмотрим.
Код выложить не могу, к сожалению. (Хотя попробую воспроизвести на минимальном примере и выложить потом). Но он достаточно бесхитростный на данном этапе. Используется класс TcpListener, в цикле вызывается метод AcceptTcpClient, клиенты обрабатываются асинхронно. Результат обработки складывается в очередь, которую разгребает некий другой поток и отправляет клиенту ответы через NetworkStream.Write().
Кстати, как показало тестирование, клиент отваливается с такой ошибкой не только при попытке записать что-то в NetworkStream (Socket), но и при чтении.
Здравствуйте, breee breee, Вы писали:
BB>Здравствуйте, v_andal, Вы писали:
_>>То есть у сервера только один поток? BB>Для каждого клиента свой поток. Вернее, все сделано через async/await и таски, поэтому в конечном счете используется пул потоков. Но ошибку я получаю при тестировании с одним клиентом, поэтому в принципе можно считать, что поток один.
Раз код посмотреть нельзя, то остаётся только совет проверять, что происходит на уровне сети. Если там всё нормально (то есть все сообщения идут без искажения и никаких лишних SYN/FIN), то возникает большой вопрос, почему системная библиотека считает, что сокет был закрыт. Но сначала, проверка
Re[3]: Помогите понять причину ошибки (unable to write data to the transport con
Здравствуйте, breee breee, Вы писали:
MD>>Почему-то есть стойкое ощущение, что сервер не успевает вычитывать запросы, поэтому в итоге решает проблему перхоти кардинально — через секир-башка.
BB>А как бы убедиться, что действительно дело в этом?
Как уже говорили выше — Wireshark или иной анализатор трафика. Надо посмотреть, что происходит с коннектом, кто шлёт (и шлёт ли вообще) FIN-пакет и т.п.
Далее, опишите, какая топология сети между клиентом и сервером? Может, там какой-то дешёвенький хаб или маршрутизатор в середине, которые тупо по железу не способны выдавать нужный packet rate — CPU не успевает, срабатывает аппаратный watch dog, перезагружающий девайс (с потерей коннекта между клиентом и сервером).
Re: Помогите понять причину ошибки (unable to write data to the transport connec
Что-то начал воспроизводить — не воспроизводится. Возможно, дело было в клиенте. Он раньше был асинхронным, а потом я его переделал на более простой синхронный. Всем спасибо за советы