Entwickler-Ecke
Basistechnologien - Mit Socket-Client senden und empfangen
sipungora - Mi 20.10.10 13:07
Titel: Mit Socket-Client senden und empfangen
Hi,
es geht um die Klient-Programmierung.
Frage 1:
Wenn ich ein Socket im Konstruktor erzeuge und in sendMessage() oder receiveMessage() ihn benutze dann funkzioniert dass nur ein mal und beim zweiten Senden kommt es zur Exception. Muss ich also immer ein neues Socket zu erzeugen, wenn ich ne neue Message senden möchte?
Etwa so:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| Socket client = new (endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(endPoint);
byte[] data = ASCIIEncoding.ASCII.GetBytes(msg); client.Send(data); client.Close(); |
Oder gibt's Möglichkeit ihn doch ein mal zu erzeugen und dann später mehrmals zu benutzen?
Frage 2:
Mein Server ist in Java umgesetzt. Wenn ich ihn mit Java-Client teste, dann läuft alles einbandfrei. Wenn ich C#-Client benutze, dann senden funktioniert, aber wird nichts empfangen. Beim Empfangen sieht das Ablauf so aus. Zuerst sende ich an den Server ein Kommando, dann sendet mir der Server eine Antwort. Mein code fürs Empfangen:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| public string receiveMessage(string command) { string stringData = null; try { Socket client = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(endPoint);
byte[] data = ASCIIEncoding.ASCII.GetBytes(command); client.Send(data); client.Close();
client = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(endPoint); data = new byte[1024]; int receivedDataLength = client.Receive(data); stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength); client.Close(); } catch (Exception ex) { throw ex; } return stringData; } |
Was mache ich falsch? Hab ich meine receive-Methode "optimal" umgesetzt? Ich bin nicht mit c#-Richtlinien bzgl. Socket-Programmierung vertraut.
Vielen Dank im Voraus.
Moderiert von
Kha: C#-Tags hinzugefügt
huuuuuh - Mi 20.10.10 13:37
zu Frage 1: Mehrmals senden mit einem Socket geht. Frag mich bitte nicht, wie^^ wie sieht denn die Exception aus?
zu Frage 2: Das Problem dabei ist, dass immer etwas "empfangen" wird, selbst wenn nichts da ist. d.h., das empfangene ist leer. Denn die Antwort ist ja nicht sofort da, sondern braucht nen paar Millisekunden zum Server und zurück. Direkt nach dem senden ist die Antwort noch nicht da, das empfangene also leer.
Du hast jetzt 2 Möglichkeiten:
*Thread.Sleep(); nutzen, um nach dem senden kurz zu warten.
*Das empfangen in einer Schleife ablaufen lassen und warten bis etwas da ist. Schlägt allerdings ziemlich auf die CPU-Auslastung.
Oder du arbeitest mit dem TcpClient und NetworkStream... (was eine ganz andere, 3. Möglichkeit wäre)
sipungora - Mi 20.10.10 14:32
huuuuuh hat folgendes geschrieben : |
zu Frage 1: Mehrmals senden mit einem Socket geht. Frag mich bitte nicht, wie^^ wie sieht denn die Exception aus?
zu Frage 2: Das Problem dabei ist, dass immer etwas "empfangen" wird, selbst wenn nichts da ist. d.h., das empfangene ist leer. Denn die Antwort ist ja nicht sofort da, sondern braucht nen paar Millisekunden zum Server und zurück. Direkt nach dem senden ist die Antwort noch nicht da, das empfangene also leer.
Du hast jetzt 2 Möglichkeiten:
*Thread.Sleep(); nutzen, um nach dem senden kurz zu warten.
*Das empfangen in einer Schleife ablaufen lassen und warten bis etwas da ist. Schlägt allerdings ziemlich auf die CPU-Auslastung.
Oder du arbeitest mit dem TcpClient und NetworkStream... (was eine ganz andere, 3. Möglichkeit wäre) |
Danke schön, huuuuuh.
Meine Exception lautet "Make sure you have not released a resource before attempting to use it". Das kann man dadurch lösen, dass man am Ende keine socket.Close() macht. Aber so wird meine Verbindung immer geöffnet und ich möchte das nicht. In der Beschreibung zur Close() steht, dass dadurch geöfnete Verbindung geschlossen wird und alle Resources befreit werden. Welche Methode kann ich danach aufrufen damit man mit dem bestehenden Socket eine neue Verbindung aufbauen kann? Ich habe probiert Bind(endPoint). Das hat nix gebracht.
Ich habe es mit dem Empfang nicht ganz verstanden. Bei mir passiert das Folgendes. Wenn die Zeile
int receivedDataLength = client.Receive(data);
erreicht wird, weiter passiert nichts. Du sagst, dass
| Zitat: |
| immer etwas "empfangen" wird |
Wieso läuft mein Programm dann nicht weiter mit receivedDataLength = 0?
Wenn ich das mit der Schleife realisiere, wie kann ich dann das Empfang testen, wenn client.Receive(data) blockiert wird?
Für Thread.Sleep() hab ich 30*1000 ms gesetzt. Das Ergebnis war gleich. Es wird beim Receive blockiert.
(Sleep rufe ich vor Receive.)
Nun probiere ich TcpClient.
huuuuuh - Mi 20.10.10 14:58
Das Receive blockiert? dann hab ich wohl was falsch gemacht, als ich mal probiert hab was mit sockets zu machen ^^
Dann vergiss alles, was ich gesagt hab, war wahrscheinlich falsch . . . :wink:
Kha - Mi 20.10.10 22:07
Normalerweise gilt: Ein Thread, eine Frage, aber da hier anscheinend beide aufs gleiche hinauslaufen: Beim Empfangen einer Antwort würde ich auf keinen Fall eine neue Connection öffnen, schließlich könnte diese erst nach dem Erhalt der Nachricht überhaupt aufgebaut sein. Solltest du einen Socket trotzdem schließen, wenn du gerade keine Antwort erwartest, brauchst du zum Wieder-Öffnen auch eine neue Socket-Instanz.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!