Ужасно медленная производительность TCPClientC#

Место общения программистов C#
Ответить
Anonymous
 Ужасно медленная производительность TCPClient

Сообщение Anonymous »

В целях обучения (я хочу получить четкое представление о внутреннем устройстве HTTP) я пишу простой HTTP-сервер, который будет анализировать запросы в соответствии с rfc7230-7235 и пересылать их на мой простой внутренний сервер.
Я не стремлюсь превзойти какое-либо существующее решение, но, очевидно, TCPClient по какой-то причине работает очень медленно. В худшем случае прямой вызов моего бэкэнда занял бы всего 20 мс, тогда как вызов с использованием моего простого сервера занял бы не менее 200 мс, что ужасно.
Не считая синтаксического анализа, который практически не влияет на время ответа, это минимальный код, который принимает ответ и отправляет его на бэкэнд как есть:

Код: Выделить всё

public static async Task Main()
{
Logger.Info("Start listener.");
var listener = new TcpListener(IPEndPoint.Parse("0.0.0.0:5000"));
listener.Start();

while (true)
{
var client = await listener.AcceptTcpClientAsync();

using var c_stream = client.GetStream();

// read request
using var ms = new MemoryStream();
int i;
var buffer = new byte[1024];
while ((i = await c_stream.ReadAsync(buffer, 0, 1024)) != 0)
{
await ms.WriteAsync(buffer, 0, i);
if (i < 1024) break;
}

// write whole request as-is to backend
using var backend = new TcpClient();
await backend.ConnectAsync(IPEndPoint.Parse("172.21.215.119:3000"));
var b_stream = backend.GetStream();

ms.Position = 0;
ms.WriteTo(b_stream);
await b_stream.FlushAsync();

// read output from backend to memory
ms.Position = 0;
while ((i = await b_stream.ReadAsync(buffer, 0, 1024)) != 0)
{
await ms.WriteAsync(buffer, 0, i);
if (i < 1024) break;
}

// send back to fuckin client
ms.Position = 0;
ms.WriteTo(c_stream);
await c_stream.FlushAsync();
}
}
Я не знаю, важно ли это, но моя среда выглядит следующим образом:
  • Я работаю на компьютере под управлением Windows 10 с WSL 2.
  • Бэкенд настроен на WSL (ubuntu). Это просто зоомагазин наnesjs.
  • Бэкенд вызывает mongodb, который настроен в среде докера (также WSL).
В моем минимальном примере кода каждый запрос занимает 200-250 мс, по крайней мере, на моей машине. Это не сильно отличается от того, как работает мой реальный код. Самая большая разница может заключаться в том, что я рассылаю спам-задачи для каждого запроса и у меня много проверок, связанных с требованиями RFC.
Если есть хорошие ресурсы о том, как правильно использовать TCPClient (или сокеты, если необходимо), то я бы с радостью воспользовался ими.

Подробнее здесь: https://stackoverflow.com/questions/704 ... -tcpclient
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»