Ich habe eine Server-Anwendung, bekomme aber einige zeitweilige Timeouts. Ich möchte sofort mit dem Schreiben auf den Client beginnen und dann den Rest meines Schreibvorgangs verschieben, bis meine Nutzlast bereit ist. Nichts, was ich in TcpClient oder NetworkStream gesehen habe, unterstützt jedoch aktives Streaming. In meinem eigenen Testbett ist jeder Schreibvorgang für den Stream isoliert, sogar die Anfangs-/Ende-Methode.Socket Constant Streaming-Daten
Zum Beispiel, in meiner Client-Seite Schreib/Lese-Schleife, sendet der folgende Server-Code nur eine einmalige Eingabe statt zwei zurück.
static void Main(string[] args)
{
var listener = TcpListener.Create(2345);
listener.Start();
while (true)
{
var client = listener.AcceptTcpClientAsync().Result;
ThreadPool.QueueUserWorkItem(async state =>
{
try
{
await HandleClient(state);
}
catch (SocketException error) when (error.Message.Contains("existing connection was forcibly closed"))
{
// do nothing
}
}, client);
}
}
private static async Task HandleClient(object state)
{
var client = (TcpClient) state;
var stream = client.GetStream();
while (true)
{
var readBuffer = new byte[4096];
var requestSize = await stream.ReadAsync(readBuffer, 0, readBuffer.Length);
var requestString = Encoding.ASCII.GetString(readBuffer, 0, requestSize);
Console.WriteLine($"[{DateTime.Now.ToLongTimeString()}] Received: {requestString}");
if (requestString == "quit")
{
break;
}
var responseString = DateTime.Now.ToLongTimeString();
var writeBuffer = Encoding.ASCII.GetBytes(responseString);
stream.BeginWrite(writeBuffer, 0, writeBuffer.Length, DelayedWriteCallback, stream);
}
client.Close();
client.Dispose();
}
private static void DelayedWriteCallback(IAsyncResult ar)
{
var stream = (NetworkStream) ar.AsyncState;
Thread.Sleep(5000);
var writeString = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString());
stream.Write(writeString, 0, writeString.Length);
stream.Flush();
stream.EndWrite(ar);
}
Wie mache ich das?
Sie rufen ein anderes BeginWrite in Ihrem DelayedWriteCallback nach dem EndWrite auf und fügen Logik hinzu, um das Senden zu beenden. Wahrscheinlich einfacher zu Aufgaben zu verwenden, vermeiden Sie den Rückruf-Aufwand. –
Leider funktioniert das nicht. Auf der Clientseite ist das Lesen abgeschlossen, und die zusätzlichen Schreibvorgänge auf dem Serverende werden erst zurückgegeben, wenn weitere Lesevorgänge ausgeführt werden. Ich möchte, dass der Client an dem gleichen Lesevorgang hängt, bis ich mit dem Schreiben fertig bin, so dass alles wie eine Anfrage/Antwort an den Client aussieht. – Bigsby
Sie verwenden dieselbe Logik auf beiden Seiten (wobei die Sockets für die Dauer beibehalten werden), wobei die Logik erkennt, wann das Ganze beendet ist. Sockets werden Bytes nur so lange mischen, wie Sie möchten. Die Bedeutung der Daten hängt von Ihren Apps ab. –