Benutzer mit den meisten Antworten
Socket Senden&Empfangen

Frage
-
Hallo!
Wie sicher ist so eine Verbindung?
Ich sende einen String, serialiere den, bis dato keine Fehler festgestellt.
Dennoch, müsste ich evtl. vorab die Länge prüfen?Es gibt ja Protokolle, die die Länge voranstellen, um das Ende mitzubekommen.
Wer stellt sicher, dass alles empfangen wird?
Macht das Microsoft intern?DataAvailable
private System.Net.Sockets.TcpClient MyTcpClient;
private System.Net.Sockets.NetworkStream MyNetworkStream;Wenn ja, wie würde man das am Sinnvollsten realisieren?
UTF8Encoding encoding = new UTF8Encoding();
byte[] ba = encoding.GetBytes(data);
System.Diagnostics.Trace.WriteLine("\r\nÜbertrage zum Server : \"" + data + "\"");
MyTcpStream.Write(ba, 0, ba.Length);byte[] buffer = new byte[MyMaxBuffer];
int gelesen = MyTcpStream.Read(buffer, 0, MyMaxBuffer);string empfangen = encoding.GetString(buffer, 0, gelesen);
Für Tipps sage ich vorab Danke.
Viele Grüße Andreas
Antworten
-
Machs do mit einer do .. while Schleife
string empfangen = String.Empty; if(MyTcpStraem.DataAvailable){ do { int gelesen = MyTcpStream.Read(buffer, 0, MyMaxBuffer); empfangen += encoding.GetString(buffer, 0, gelesen); }while (MyTcpStraem.DataAvailable) }
Florian Kowalsky -> If it was helpful please mark ist as helpful!!- Als Antwort markiert Andreas Bauer2 Dienstag, 3. Mai 2011 18:28
Alle Antworten
-
Hallo Andreas,
anders gefragt: Warum verwendest Du überhaupt Sockets? Je nach Anforderung gibt es u.U. schon fertige Lösungen, die für dich erheblich weniger Arbeit bedeuten, eben weil dort schon sämtliche Prüfungen, ... im Vorfeld stattfinden und Du dann "nur noch" mit den Daten arbeiten musst.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Machs do mit einer do .. while Schleife
string empfangen = String.Empty; if(MyTcpStraem.DataAvailable){ do { int gelesen = MyTcpStream.Read(buffer, 0, MyMaxBuffer); empfangen += encoding.GetString(buffer, 0, gelesen); }while (MyTcpStraem.DataAvailable) }
Florian Kowalsky -> If it was helpful please mark ist as helpful!!- Als Antwort markiert Andreas Bauer2 Dienstag, 3. Mai 2011 18:28
-
anders gefragt: Warum verwendest Du überhaupt Sockets? Je nach Anforderung gibt es u.U. schon fertige Lösungen, die für dich erheblich weniger Arbeit bedeuten, eben weil dort schon sämtliche Prüfungen, ... im Vorfeld stattfinden und Du dann "nur noch" mit den Daten arbeiten musst.
Hallo,
wie meinst Du das? Ironisch?
Wa soll ich verwenden?
Andreas
-
string empfangen = String.Empty; if(MyTcpStraem.DataAvailable){ do { int gelesen = MyTcpStream.Read(buffer, 0, MyMaxBuffer); empfangen += encoding.GetString(buffer, 0, gelesen); }while (MyTcpStraem.DataAvailable) }
Hallo Florian,
ok, das heißt ein vorheriges Senden der Anzahl ist nicht notwendig.
Also in etwas so
4 Byte die Länge + Telegramm ?
So wäre es ja einfacher.
Andreas
-
Hallo Andreas,
wie meinst Du das? Ironisch?
Wa soll ich verwenden?
Das kommt auf deine Anforderungen an. Evtl. hast Du die schon mal in einem anderen Thread beschrieben. Falls ja, poste doch bitte mal einen Link.
Einfaches Beispiel: Um Daten an einen Webservice zu übertragen, schreibt man auch nicht alles von Hand, sondern nutzt bspw. ASP.NET Webservices, WCF, .... Für die Übertragung selbst dann bspw. Json, Xml, ...
Dass das evtl. nicht genau bei dir passt, ist klar. Daher ja auch die Frage: Was machst Du da eigentlich genau? Evtl. gibt es ja dann erheblich einfachere Lösungen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Das kommt auf deine Anforderungen an. Evtl. hast Du die schon mal in einem anderen Thread beschrieben. Falls ja, poste doch bitte mal einen Link.
Einfaches Beispiel: Um Daten an einen Webservice zu übertragen, schreibt man auch nicht alles von Hand, sondern nutzt bspw. ASP.NET Webservices, WCF, .... Für die Übertragung selbst dann bspw. Json, Xml, ...
Dass das evtl. nicht genau bei dir passt, ist klar. Daher ja auch die Frage: Was machst Du da eigentlich genau? Evtl. gibt es ja dann erheblich einfachere Lösungen.
Hallo Stefan,
ok. Ich dachte halt weil ich so oft frage.
http://social.msdn.microsoft.com/Forums/de-DE/visualcsharpde/thread/f2b53154-fb7a-4352-9758-4152014ae679
http://social.msdn.microsoft.com/Forums/de-DE/visualcsharpde/thread/d5a8ce50-446c-4cb8-9132-87c224ec9427Ja ich hatte große Probleme mit dieser Herausforderung und war froh es einigermaßen zum Laufen gebracht haben.
Tut auch.
Es kam die Frage auf, wie stelle ich sicher, dass alles empfangen wurde.http://de.wikipedia.org/wiki/Byte_Order_Mark
http://de.wikipedia.org/wiki/Big_endian
Muss man das so kompliziert machen? Bietet Windows was?
Braucht man das?Fragen über Fragen.
Die Idee von Florian ist gut und verständlich.
OK vielleicht über SOAP irgendwas noch...?
Andreas
-
Hallo Andreas,
zu Deiner Frage habe ein paar Anmerkungen.
Zum ersten ist es wichtig zu wissen, dass Verfahren die intern ein Msg-Peek (Abfrage) auf dem Socket umsetzen (auch das DataAvailabe), normal nicht zu empfehlen sind.
[INFO: Avoid Data Peeking in Winsock]
http://support.microsoft.com/kb/192599/en-usAus: http://www.cetix.de/DotNetNews/Thread94063-prfen_ob_TCClient_noch_da_ist.aspx:
- ... solche Schleifen mit 'DataAvailable' und Sleep sind höchst unüblich/unsauber... (und beendete Verbindungen bemerkt man so nicht). Vergiss 'DataAvailable', mache eine ordentliche Lese-Schleife mit synchron Socket.Receive / NetworkStream.Read
oder asynchron (Vorsicht, Callback erfolgt mit Pool-Threads) Socket.BeginReceive / NetworkStream.BeginRead
oder eben u.U. halt Socket.Select/Socket.Poll.
Aus: http://www.eggheadcafe.com/software/aspnet/36133229/prob-mit-image-via-tcp-senden-und-empfangen.aspx:
- ... 'DataAvailable' ist ein relativ untaugliches Kriterium.
Microsoft hat hier kein Standard-Verfahren wie es das standardmäßig macht, sondern Szenarien-abhängig.
Allerdings "wenn" eine Länge mit gesendet werden soll, dann wird normal 4 Byte am Anfang benutzt und dann der Daten tragende serialisierte Stream.
[Data Driven Silverlight Applications for the Enterprise]
http://msdn.microsoft.com/en-us/magazine/dd315415.aspxsiehe dort: "Figure 6 Layout of the Serialized NetworkMessage Types"
Eine solche Vorschaltung eines int's in den NetworkStream ist möglich, aber nicht notwendig.
Bei kleiner ReceiveBufferSize, SendBufferSize kann hier ggf. durchaus ohne solche Längen gearbeitet werden.
Es gibt verschiedene Ansätze und Verfahren.Hier ein auch Beispiel:
[Client-Server Kommunikation mit dem TcpClient und TcpListener]
http://dzaebel.net/TcpClientServer.htmes geht natürlich auch asynchron:
[Asynchronous Server Socket using C# | C# Help]
http://www.csharphelp.com/2007/02/asynchronous-server-socket-using-c/
ciao Frank - ... solche Schleifen mit 'DataAvailable' und Sleep sind höchst unüblich/unsauber... (und beendete Verbindungen bemerkt man so nicht). Vergiss 'DataAvailable', mache eine ordentliche Lese-Schleife mit synchron Socket.Receive / NetworkStream.Read
-
[Client-Server Kommunikation mit dem TcpClient und TcpListener]
http://dzaebel.net/TcpClientServer.htmprivate void btnOK_Click(object sender, EventArgs e) { try { tcpStream = tcpClient.GetStream(); UTF8Encoding encoding = new UTF8Encoding(); //Arbeiten Sie hier später über Decoder! Thema Fragmentierung von Doppelbytes. byte[] ba = encoding.GetBytes(txtÜbertragungstext.Text); Melde("\r\nÜbertrage zum Server : \"" + txtÜbertragungstext.Text + "\""); tcpStream.Write(ba, 0, ba.Length); byte[] buffer = new byte[maxBuffer]; int gelesen = tcpStream.Read(buffer, 0, maxBuffer); string empfangen = encoding.GetString(buffer,0,gelesen); Melde("Empfangen: \"" + empfangen + "\""); } catch (Exception exp) { Melde(exp.Message); return; } }
Hallo Frank , so habe ich es ja übernommen und festgestellt, dass Read halt liest.
Grüße Andreas
-
Florian Kowalsky -> If it was helpful please mark ist as helpful!!
Hallo Florian,ich habe es erst so
TcpClient MyTcpClient; //Stream MyTcpStream; NetworkStream MyTcpStream;
Deshalb kannte ich DataAvailable nicht.
Trotzdem es sind Daten da, es wird nicht gesetzt. Und nun?
Es wäre zumindest eine einfache verständliche Lösung.
http://www1.minpic.de/bild_anzeigen.php?id=145091&key=34843918&ende
Ist ja auch so gemacht.
http://msdn.microsoft.com/de-de/library/system.net.sockets.networkstream.dataavailable.aspx
Andreasstring empfangen = String.Empty; int gelesen = 0; if (MyTcpStream.CanRead) { byte[] buffer = new byte[MyMaxBuffer]; //if (MyTcpStream.DataAvailable) //{ do { gelesen = MyTcpStream.Read(buffer, 0, MyMaxBuffer); //empfangen = encoding.GetString(buffer, 0, gelesen); empfangen += encoding.GetString(buffer, 0, gelesen); } while (MyTcpStream.DataAvailable); //} }