Furchtbar langsame Leistung von TCPClientC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Furchtbar langsame Leistung von TCPClient

Post by Anonymous »

Zu Lernzwecken (ich möchte mich mit HTTP-Interna vertraut machen) schreibe ich einen einfachen HTTP-Server, der Anfragen gemäß rfc7230-7235 analysiert und an meinen einfachen Backend-Server weiterleitet.
Ich habe nicht vor, eine bestehende Lösung zu übertreffen, aber anscheinend arbeitet TCPClient aus irgendeinem Grund sehr langsam. Ein direkter Aufruf an mein Backend würde im schlimmsten Fall nur 20 ms dauern, wenn er über meinen einfachen Server aufgerufen würde, würde das mindestens 200 ms dauern, was schrecklich ist.
Abgesehen vom Parsen, das die Antwortzeit größtenteils unbedeutend in Anspruch nimmt, ist dies minimaler Code, der die Antwort entgegennimmt und sie so wie sie ist an das Backend sendet:

Code: Select all

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();
}
}
Ich weiß nicht, ob das wichtig ist, aber meine Umgebung sieht so aus:
  • Ich arbeite auf einem Windows 10-Rechner mit WSL 2.
  • Das Backend ist auf WSL (Ubuntu) eingerichtet. Es ist nur ein Zooladen auf NestJS.
  • Das Backend ruft Mongodb auf, das in der Docker-Umgebung (auch WSL) eingerichtet ist.
In meinem minimalen Codebeispiel dauert jede Anfrage 200–250 ms, zumindest auf meinem Computer. Es unterscheidet sich nicht wesentlich von der Funktionsweise meines tatsächlichen Codes. Der größte Unterschied könnte sein, dass ich Aufgaben für jede Anfrage spamme und viele Validierungen im Zusammenhang mit RFC-Anforderungen habe.
Wenn es einige gute Ressourcen zur korrekten Verwendung von TCPClient (oder Sockets, falls erforderlich) gibt, dann würde ich sie gerne annehmen.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post