![]() |
[C#/.NET] Client-Listener möglich?
Hi,
ich hab ein Projekt in C#, das über TCP als Client mit einem Server kommuniziert. Wenn ich dem Server nun beispielsweise ein Kommando sende, dann schickt dieser mir das, was ich mit diesem Kommando anfordere. Quasi das Ping-Pong-Prinzip. Das kann ein riesiger Datensatz sein oder nur die Uhrzeit. Mit den normalen System.Net.Socket's / TcpClient funktioniert das auch wunderbar, solang bekannt ist, wieviel der Server bei einer bestimmten Anfrage sendet. Nun gibt es hier ein Problem. Auf ein Request des Clients können auch mal 2-3 Antworten total unterschiedlicher Länge vom Server kommen. Zwischen diesen Antorten kann - der Server ist sehr komplex und hat in Hochzeiten auch viel zu tun - auch durchaus mal eine längere Zeitspanne liegen. Ich hab es jetzt schon gelöst, nur is die Lösung wirklich sehr quick und verdammt dirty ;-) Aufbau ist wie folgt (Pseudo):
Code:
Dabei mache ich mir die Eigenschaft zunutze, dass der Server bei jedem Antworten-Paket ein bestimmtes Kommando am Ende sendet. Quasi ein "das wars, dass sind die Daten zu deinem Request". Ich hab deswegen einfach eine Schleife gemacht die solange "empfängt", bis der empfangene String auch das Abbruchkommando enhält.
TcpClient tcp = new TcpClient();
NetworkStream str = tcp.GetStream(); BinaryReader reader = new BinaryReader(str); BinaryWriter writer = new BinaryWriter(str); ... byte[] dummy = new byte[1]; String buffer = ""; do { reader.read(dummy,0,1); buffer += B2S(dummy); //B2S = Byte[]ToString, eigene Funktion, funktioniert auch } while (! buffer.contains(ENDKOMMANDO)) Allerdings gibts daher auch 100% Auslastung. Gibt es nicht irgendeine Möglichkeit quasi ein Client-Listener zu machen, vll ne Callback-Funktion die automatisch horcht ob Daten vom Server kommen? Danke im Voraus und schönen Feiertag ;-) |
Re: [C#/.NET] Client-Listener möglich?
Du könntest das ganze über die Client-Eigenschaft des TCPClienten lösen. Dabei handelt es sich um das zugrundeliegende Socket, welches auch asynchrones Empfangen von Daten ermöglicht. ->
![]() ![]() |
Re: [C#/.NET] Client-Listener möglich?
Danke dir, die Funktionen hab ich auch schon gesehen. Wusste nur nicht, ob das der richtige Weg ist. Hättest du vielleicht ein etwas angewandteres Beispiel als das des MSDN? Sprache ist dabei ja egal.
|
Re: [C#/.NET] Client-Listener möglich?
Code:
public class AsyncObject
{ public bool Connected = false; // ID received flag public Socket Socket = null; // Client socket. public const int BufferSize = 1024; // Size of receive buffer. public byte[] Buffer = new byte[BufferSize];// Receive buffer. public List<byte> Received = new List<byte>(); }
Code:
protected void ReadCallback(IAsyncResult ar)
{ String content = String.Empty; AsyncObject state = (AsyncObject)ar.AsyncState; Socket handlersocket = state.Socket; try { // Read data from the client socket. int bytesRead = handler.EndReceive(ar); if (bytesRead > 0) { state.Received.AddRange(state.Buffer); content = B2S(state.Buffer); if ((content.Length > 0) && content.Contains(ENDKOMMANDO)) { HandleMessages(state, state.Received); } else { // Nicht alle Daten wurden empfangen handlersocket.BeginReceive(state.Buffer, 0, AsyncObject.BufferSize, 0, new AsyncCallback(this.ReadCallback), state); } } else { // Disconnected } } catch (System.Net.Sockets.SocketException es) { if (es.ErrorCode != 64) { Console.WriteLine(string.Format("Socket Exception: {0}, {1}.", es.ErrorCode, es.ToString())); } } catch (Exception e) { if (e.GetType().FullName != "System.ObjectDisposedException") { Console.WriteLine(string.Format("Exception: {0}.", e.ToString())); } } }
Code:
AsyncObject state = new AsyncObject();
state.Socket = tcp.Client; tcp.Client.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(this.ReadCallback), state); |
Re: [C#/.NET] Client-Listener möglich?
Sehr schön, werde den Code mal durcharbeiten und schauen, ob das mein Problem löst!
Mal noch zum Verständnis, synchron bedeutet in dem Fall, dass mein Client eine Anfrage macht und dann solange wartet (blockiert), bis der Server eine Antwort gibt. Es läuft immer nach dem Schema Anfrage - Antwort. Asynchron bedeutet, der Client sendet eine Anfrage und es muss keine direkte Antwort kommen, das Clientprogramm kann quasi weiterarbeiten (blockiert nicht) und wartet dabei im Hintergrund ständigt auf eventuelle Daten des Servers? [Edit] Nach ein wenig zurechtschneiden des Codes funktioniert er super, vielen Dank!!! Es ist zwar "langsamer" als synchron, aber das ist nicht schlimm. Nur wieso eigentlich? Also es gibt beispielsweise ein Kommando, wo ich die Antwort weiß. Wenn ich dieses sende und die Antwort synchron wieder emfpange, geht das instantan sofern der Server nicht viel zu tun hat. Bei der asynchronen Lösung braucht er ein paar Sekunden bis er nach gesendetem Kommando in die Callback-Funktion eintritt. Weiß jemand woran das liegt? [/Edit] |
Re: [C#/.NET] Client-Listener möglich?
OK Nachtrag, nur die erste Antwort des Servers lässt kurz auf sich warten, danach geht es sehr schnell.
Liegt also wohl eher am Server als am Clienten. Daher ist das die ideale Lösung für das Problem! :thumb: |
AW: [C#/.NET] Client-Listener möglich?
Hi Flips !
ich habe ich selber problem wie du , ich habe schon ein Server , der von Delphi programmiert wurde und versuche ich ein Client mit C# zu programmieren. Mein Problem ist, dass wenn mein Client die data anfragt, der Server Anwortet nicht. mein grund idee ist : Der Client soll eine Anfrage senden und soll es Antwort bekommen. ich bin anfänger bei TCP/ip programmierung. Hiermit möchte ich wissen, ob du noch dein code hast? wenn ja, könntest du mir es zu schicken? merci d'avance Tek |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz