C# CryptoStream über einen NetworkStream

Zhen

Lt. Junior Grade
Registriert
Aug. 2009
Beiträge
299
Hallo Leute,
wieder mal ein Problem bei dem ich selber nicht wirklich klar komme!

Ich entwickel gerade eine Netzwerkanwendung und da die Übertragung verschlüsselt ablaufen soll habe ich mich dazu entschlossen den CryptoStream zu verwenden!

Eigentlich klappt ja fast alles schon ganz gut, aber ein Problem hätte ich da dennoch.

Ich benutze den TcpClient und TcpListener für meine Anwendung. Den Cryptostream erstelle ich indem ich die TcpClient.GetStream() Methode beim instanzieren der CryptoStream-Klasse verwende. Klappt so weit so gut.

Ich bekomme die Daten auch bereits ans andere Ende der Leitung und auch den übermittelten Text angezeigt, aber nach dem Text kommen lauter verschiedene komische Zeichen. Ich dachte zuerst es könnte an nem Leerschritt oder sowas liegen, aber auch die Trim-Methode hilft hier nicht weiter.

Zum versenden und Empfangen der Nachricht verwende ich TcpClient.Client.Send() und TcpClient.Client.Receive() Methoden.

PS: im Anhang kurzer Screenshot wie das ganze aussieht wenn ich die Nachricht am anderen Ende empfange!!
 

Anhänge

  • screen.jpg
    screen.jpg
    68,8 KB · Aufrufe: 485
Eventuell passt die Größe/Längenangabe der zu verschickenden bzw. zu empfangenden Daten nicht, prüf das doch mal.
 
Hmm.... also daran dacht ich auch, aber ich seh da kein Fehler! Ich hab sogar extra noch ein zweites Array erstellt das genauso groß ist wie der Inhalt (da der Buffer ja größer ist), wo ich dann die vorhanden Bytes aus dem Buffer reinschreibe.

Ich poste mal gleich den Quelltext. Hoffe ihr könnt mir dann helfen ^^
Ergänzung ()

Der Server der die Nachricht empfängt:

Code:
while (client == null) {
				client = listener.AcceptTcpClient();
			}

			byte[] buffer = new byte[1024];
			client.Client.Receive(buffer, 0, buffer.Length, SocketFlags.None);

			MemoryStream ms = new MemoryStream(buffer);
			crypt = new CryptoStream(ms, provider.CreateDecryptor(), CryptoStreamMode.Read);

	try {
					crypt.Read(buffer, 0, buffer.Length);
				} catch {
				}

			string message = Encoding.UTF8.GetString(buffer);

			Console.WriteLine(message);



Der Client der die Nachricht verwendet:

Code:
client.Connect(ipEP);

ms = new MemoryStream();

crypt = new CryptoStream(ms, provider.CreateEncryptor(), CryptoStreamMode.Write);

byte[] array = Encoding.UTF8.GetBytes("Das ist ein Test!");

crypt.Write(array, 0, array.Length);
crypt.FlushFinalBlock();

client.Client.Send(ms.ToArray(), 0, ms.ToArray().Length, SocketFlags.None);
 
byte[] buffer = new byte[1024];

Du sagst in der Receive-Methode, dass du explizit 1024 Bytes möchtest. Also kriegst du deinen String + irgendwas, bis der Buffer voll ist.
 
nja ich weiß ja nicht wie groß der buffer sein soll. außerdem hab ich es auch anders schon probiert und trotzdem das selbe ergebnis bekommen.


Code:
int i = 0;

			do {
				try {
					buffer[i] = (byte)crypt.ReadByte();
					i++;
				} catch {
					break;
				}
			} while (true);

			byte[] data = new byte[i];

			while(i != 0) {
				data[i] = buffer[i];
			}

damit hab ichs auch schon probiert. selbiges Ergebnis obwohl das data-array genauso groß ist wie der inhalt. crypt.ReadByte() wirft nämlich ne exception sobald ein 0-Byte im buffer kommt. Das ist dann der Fall wenn der Buffer nicht vollständig gefüllt wird.

Ich glaub langsam, dass es an dem FlushFinalBlock() liegt, aber wenn ich den nicht verwende, dann bekomme ich zwar den String (bis auf das letzte Zeichen "!") + wieder das gewürschtel! :(
Ergänzung ()

Na gut jetzt hab ich es etwas anders probiert. Bevor ich den String übergeben habe, habe ich erstmal die Länge des Byte-Arrays verschickt. Beim Server habe ich dann diese Empfangen und einen Puffer mit der Länge erstellt. Hat schon mal besser geklappt als das davor, aber trotzdem gibt er mir folgendes aus:

Das ist ein Test!^{??I???Q?h??

Und jetzt bin ich auch komplett am Ende mit meinem Latein. Außerdem finde ich, dass es keine wirklich saubere Programmierung ist, wenn ich erstmal jedes mal bevor ich was verschicke die Größe senden muss!

Hat jemand ne Lösung oder ne Idee? Danke schon mal im vorraus!
 
Gibt es nicht schon irgendwas "fertiges" in .NET, um verschlüsselte Daten zu übermitteln? Hat es einen Grund, wieso du nicht WCF verwendest? Da geht so etwas deutlich einfacher und sicherer.

Dass du zuviele Zeichen rausbekommst, kann auch der Entschlüsselung liegen. Generell wird nicht Zeichen für Zeichen entschlüsselt, sondern meist Blocks (fester) Größe. Daher wird zum Entschlüsseln demnach auch mehr benötigt, wenn es nicht durch deinen String völlig ausgefüllt ist. Das Auffüllen macht dann schon der Verschlüssler. Das ganze Thema ist nicht wirklich einfach, dazu sollte man sich schon genau einlesen, wie das genau funktioniert... Meine Beschreibung ist auch nur sehr vage, aber ich bin ziemlich sicher dass es damit zusammenhängt.

Mein Tipp wäre, WCF zu verwenden.
 
Sind WCF nicht einfache Dienste? Deswegen müssen sie doch trotzdem mit C# Klassen gecodet werden. in C# gibts aber nur SslStream-Klasse und CryptoStream-Klasse. Wobei die CryptoStream-Klasse in meinem Anwendungsfall sich besser eignet. (Also das ist zumindestens das was ich so über WCF gehört habe, falls ich mit WCF falsch liege dann lasse ich mich gerne eines besseren behleren. Bin schileßlich noch Anfänger und hat mit WCF bislang nichts am Hut).

Desweiteren soll es ja kein Dienst werden, sondern Bestandteil eines Tools.

PS: ich habe übrigens das Problem ganz einfach indem gelöst, dass ich auf der Client Seite am Ende des Strings ein "<EOF>" setze und auf der Serverseite dann einfach dieses und alles was dahinter kommt abschneide!

Sollte es eine bessere Möglichkeit geben dann bin ich immer ganz Ohr ;-)

Vielen Dank übrigens für die Tipps. :)
Ergänzung ()

Ok vielleicht hat es sich doch nicht erledigt. Jetzt kann ich zwar Strings problemlos übermitteln, aber falls es mal Bilder oder so sein sollten, dann hab ich wieder die selben schwierigkeiten wahrscheinlich -_-"

Ich hass sowas xD werd aber mal dran bleiben. Irgendwie klappt das dann schon ;-)
 
Das mit dem EOF ist schonmal keine schlechte Idee ;)

Was genau verstehst du unter einem "einfachen Dienst"? :) Was du da programmierst, ist so gesehen ja auch ein "einfacher Dienst" ;) Mit WCF machst du genau das gleiche, nur ohne direkt TCP und Bytes zu verwenden. Stattdessen sendest du echte typisierte Objekte (die serialisierbar sein müssen), und die hast du dann im Client, ohne dass du dich über die Übertragung kümmern musst.

Im Prinzip machst du mit WCF nix anderes als du jetzt mit TCP, nur eben nicht direkt über TCP sondern die so genannten Bindings. Such mal im Netz nach WCF Tutorials, da gibts jede Menge, das ist wirklich nicht schwer und wird dir viel Arbeit und Ärger ersparen (Bilder und komplexe Datentypen de-/serialisieren...)
 
Ok vielen Dank, werd mich da gleich mal erkundigen bevor ich mit meinem Projekt hier weiter mache ^^

Mit den TcpClients (oder auch Sockets) hab ich an einigen Stellen nämlich tatsächlich nur Schwierigkeiten. :D
Ergänzung ()

Okk.... also WCF sieht schon mal sehr interessant aus, aber irgendwie ist das doch ganz schön kompliziert ^^

Werde aber bei meinem Projekt nun wohl doch auf WCF setzen. Vielen vielen Dank für den Tipp. Falls du einige gute Bücher oder Tutorials dazu kennst, dann wäre ich sehr dankbar wenn du sie hier posten könntest =)

Danke nochmals.
 
Auf der Serverseite:
Code:
CryptoStream crypt = new CryptoStream(client.GetStream(), provider.CreateDecryptor(), CryptoStreamMode.Read);
byte[] buffer = new byte[1024];
int bytes = crypt.Read(buffer, 0, buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
Console.WriteLine(chars.toString());
 
1.) Das Grundproblem ist, dass sämtliche vordefinierte CryptoStreams in .NET bzw. sogar die Algorithmen dahinter nur für das Verschlüsseln von Dateien gedacht sind d.h. man öffnet den Stream, schreibt alles hinein und schließt ihn dann. Wenn du einzelne Nachrichten verschicken willst, dann haut das nicht so ganz hin.

2.)
client.Client.Receive(buffer, 0, buffer.Length, SocketFlags.None);

Das kann ganz schön ins Auge gehen. Das Read Kommando wartet solange, bis Daten im Netzwerkbuffer stehen. Dann werden alle Daten gelesen. Solange du nur lokal am selben Rechner testest, wird das die meiste Zeit hinhauen, übers Netzwerk bzw. sogar übers Internet dann nicht mehr. Du musst immer den Rückgabewert von Read bzw. Receive überprüfen. Die von dir angegebenen Länge ist nur ein Maximallänge. Das haut dann zwar manchmal mit deinen Teststrings hin, nicht aber mit größeren Datenblöcken wie Grafiken. Das das Ganze vom Füllstand der Buffer abhängt ist es auch nicht reproduzierbar.

Genau hier fängt es dann an kompliziert zu werden, wenn du mehr als eine Nachricht gleichzeitig versendest. Du weißt im Vorhinein nicht, welche Daten zur ersten Nachricht gehören und welche zur zweiten. Unverschlüsselt ist das egal, weil die gelesenen Daten einfach kombinierst. Bei den meisten Algorithmen haut das aber nicht hin.

3.) Die Methode FlushFinalBlock() ist wie der Name schon sagt gedacht, den letzten Block zu schreiben. Da wird nicht sehr viel Sinnvolles heraus kommen, wenn du dann noch Daten hinterher schiebst.

4.) Ich habe es bei mir bisher so gelöst:
a) Ich nehme einen MemoryStream
b) Ich stopfe den MemonryStream in einen CryptoStream
c) Ich schreibe die unverschlüsselten Daten in den CryptoStream und schließe diesen.
d) Ich habe die verschlüsselten Daten im MemoryStream, wo ich sie mir als Array heraushole
e) Ich übertrage unverschlüsselt die Länge der verschlüsselten Daten (4Byte - Integer)
f) Ich übertrage die verschlüsselten Daten.

Am Client lese ich in einer Schleife so lange mit Read, bis ich 4 Byte habe.
Dann berechne ich die Länge und lese in einer nächsten Schleife so lange weiter, bis ich alle verschlüsselten Daten habe.
Das Ganze stopfe ich wieder in einen CryptoStream mit einem MemoryStream dahinter und hole mir die Daten heraus.

5.) Weiters solltest du dir um den sicheren Verbindungsaufbau Gedanken machen.
Bei mir schaut das Versenden von verschlüsselten Daten so aus:

Sender:
a) Ich generiere meinen asymetrischen Key (z.B. RSA)
b) Ich versende meinen öffentlichen RSA Key
Empfänger:
c) Ich lese den öffentlichen RSA Key
d) Ich generiere meinen symetrischen Key (z.B. DES, TrippleDES etc.)
e) Ich verschlüssle meinen DES Key mit dem öffentlichen RSA Key des Senders.
f) Ich versende den verschlüsselten Key
Sender:
g) Ich lese den verschlüsselten Key und entschlüssle ihn mit meinem privaten RSA Key
h) Ich sende die Daten an den Empfänger

Bei meiner Anwendung war es bisher so, dass ich immer nur gewisse Teile verschlüsselt habe (z.B. Passwörter). Wenn die ganze Kommunikation verschlüsselt wird (größere Datenmengen), dann macht es eventuell Sinn das Protokoll so zu optimieren, dass beim Verbindungsaufbau gleich beide ihre Keys austauschen statt für jeden Nachrichtenblock einzeln.

@lynxx:
CryptoStream crypt = new CryptoStream(client.GetStream(), provider.CreateDecryptor(), CryptoStreamMode.Read);
byte[] buffer = new byte[1024];
int bytes = crypt.Read(buffer, 0, buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
Console.WriteLine(chars.toString());

Das funktioniert so auch nicht ganz. UTF8 ist eine Codierung mit variabler Bytelänge d.h. normale ASCII Zeichen sind 1 Byte lang, regionale Sonderzeichen wie z.B. ä,ö,ü oder auch alle russischen/chinesischen Zeichen sind 2 oder mehr Bytes lang.

Wenn du z.B. den String "Tschüss" sendest und nur die ersten 5 Bytes per Read bekommst, dann bekommst du "Tsch" und das erste Byte des ü, das er aber nicht interpretieren kann d.h. nur "Tsch".
Beim zweiten Read bekommst du dann das zweite Byte von "ü" und "ss". Mit dem zweiten Byte des ü kann er auch nichts anfangen und du wirst insgesamt nur "Tschss" erhalten bzw. eventuell ein paar Fragezeigen dazwischen.
 
Zuletzt bearbeitet:
andr_gin schrieb:
1.) Das Grundproblem ist, dass sämtliche vordefinierte CryptoStreams in .NET bzw. sogar die Algorithmen dahinter nur für das Verschlüsseln von Dateien gedacht sind d.h. man öffnet den Stream, schreibt alles hinein und schließt ihn dann. Wenn du einzelne Nachrichten verschicken willst, dann haut das nicht so ganz hin.

Das ist alles Unsinn, was hier verzapft wird. CryptoStream ist einfach nur eine .NET Klasse, die als Wrapper für Dateistreams, die mit kryptographischen Algorithmen arbeiten, dient.

Für die Anwendung ist es irrelevant, ob sie in eine Datei oder zu einem Socket schreibt.

Auf der MSDN-Seite wird CryptoStream mit dem Rijandel verwendet. Das ist ein symmetrisches Kryptosystem, besser bekannt als AES.

Für Client-Client-Verschlüsselungen ist RSA besser geeignet bzw. eine Hybridverschlüsselung.

Das was hier abgezogen wird, ist Senden über TCP. TCP kennt aber keine Nachrichtengrenzen, deshalb muss man wissen, wie groß die verschlüsselten Daten sind. Um in TCP Nachrichtengrenzen zu erkennen, ist entweder ein Anwendungsprotokoll erforderlich, oder man sendet immer gleich lange Datenpakete.

Ich empfehle folgende Seite:

http://www.codeplanet.eu/tutorials/csharp/66-client-server-modell.html

Dort wird ein Nachrichtenaustauschsystem (mit Anwendungsprotokoll) für TCP entwickelt. Es steht auch der AES zur Verfügung.

Ein Paket sieht dort so aus.

Client-Server-Model%20Packet.png


Man sieht, es hat einen Header, gefolgt von Daten.

Genauso funktioniert auch das Internet, paketorientiert!
 
Vielen Dank für euren ganzen Beiträge. Werde ich mir auf jeden Fall zu Herzen nehmen und mich etwas damit spielen. Als leihe ist es bloß doch etwas schwer da richtig reinzukommen bzw. dauert halt länger ^^

aber irgendwie pack ich das schon =)
 
Stefan_Sch schrieb:
Das ist alles Unsinn, was hier verzapft wird. CryptoStream ist einfach nur eine .NET Klasse, die als Wrapper für Dateistreams, die mit kryptographischen Algorithmen arbeiten, dient.

Für die Anwendung ist es irrelevant, ob sie in eine Datei oder zu einem Socket schreibt.

Theoretisch ja. Der Unterschied ist nur, dass wenn du in eine Datei schreibst, ist es egal, ob der Stream die Daten erst beim Schließen weiter leitet oder gleich sofort, da dazwischen sowieso alles undefiniert ist. Bei einem NetworkStream willst du aber, dass die Daten SOFORT gesendet werden, da du ja eine Antwort haben willst.

Für Client-Client-Verschlüsselungen ist RSA besser geeignet bzw. eine Hybridverschlüsselung.

RSA ist ca. um den Faktor 1.000 lansamer als DES, AES etc. Das ist zum Verschlüsseln größerer Datenmengen völlig ungeeignet und funktioniert mit der Implementation von .NET auch gar nicht.
RSA ist dafür gedacht, einen sicheren Schlüsselaustausch zu gewährleisten, wie von mir oben beschrieben. Per RSA werden die DES/AES Schlüssel sicher übermittelt und dann geht es symmetrisch weiter.

Das was hier abgezogen wird, ist Senden über TCP. TCP kennt aber keine Nachrichtengrenzen, deshalb muss man wissen, wie groß die verschlüsselten Daten sind. Um in TCP Nachrichtengrenzen zu erkennen, ist entweder ein Anwendungsprotokoll erforderlich, oder man sendet immer gleich lange Datenpakete.

Da hast du Recht. Gleich lange Datenpakete sind aber in der Praxis ziemlich mühsam. Ich mache das immer so:

Byte 0: Der Typ der Nachricht
Byte 1-4: Die Länger der darauf folgenden Daten in Byte
Byte 5-?: Die Daten

Damit habe ich nicht nur die Länge übertragen, sondern ich weiß auch gleich, was die Bedeutung der Daten ist, die da daher kommen z.B. das Kommando Login oder das Kommando GetFile. Kommt ein Kommando daher, das ich nicht erwartet habe, dann ist die Verbindung asynchron geworden und ich werde eine Exception.

http://www.codeplanet.eu/tutorials/csharp/66-client-server-modell.html

Dort wird ein Nachrichtenaustauschsystem (mit Anwendungsprotokoll) für TCP entwickelt. Es steht auch der AES zur Verfügung.

Ein Paket sieht dort so aus.

Client-Server-Model%20Packet.png


Man sieht, es hat einen Header, gefolgt von Daten.

Genauso funktioniert auch das Internet, paketorientiert!

Wenn man ausschließlich TCP verwendet, braucht man das gar nicht so kompliziert implementieren. Da reichen mein 5 Byte Header.
Natürlich ist es es sehr ratsam, wenn man sich mit den darunter liegenden Protokollen auch etwas beschäftigt zur Fehlersuche etc., aber rein für den Programmablauf reicht es, wenn man weiß, dass man einen Stream hat.

In den meisten Fällen kommt man mit TCP aus. Man sollte nur TcpClient.NoDelay = True setzen, sonst wird die Verbindung ziemlich zäh, wenn sich die Senderichtung oft ändert und man hat selbst im LAN Latenzen um die 200-500ms.
 
andr_gin schrieb:
Theoretisch ja. Der Unterschied ist nur, dass wenn du in eine Datei schreibst, ist es egal, ob der Stream die Daten erst beim Schließen weiter leitet oder gleich sofort, da dazwischen sowieso alles undefiniert ist. Bei einem NetworkStream willst du aber, dass die Daten SOFORT gesendet werden, da du ja eine Antwort haben willst.

Darauf antworte ich am Ende, weil du dort noch einmal das Thema anschneidest.

andr_gin schrieb:
RSA ist ca. um den Faktor 1.000 lansamer als DES, AES etc. Das ist zum Verschlüsseln größerer Datenmengen völlig ungeeignet und funktioniert mit der Implementation von .NET auch gar nicht.
RSA ist dafür gedacht, einen sicheren Schlüsselaustausch zu gewährleisten, wie von mir oben beschrieben. Per RSA werden die DES/AES Schlüssel sicher übermittelt und dann geht es symmetrisch weiter.

Das hast du schlau erkannt. Deshalb nannte ich auch die Hybridverschlüsselung. Diese stellt nämlich die Kombination aus symmetrischen und asymmetrischen Kryptoverfahren dar. Beispielsweise dem RSA und dem AES.

Für den sicheren Schlüsselaustausch, wird RSA verwendet, für die eigentliche Verschlüsselung der Daten, der AES. Für kleine Datenpakete reicht sogar auch der RSA allein aus. Theoretisch können mit RSA übrigens Daten beliebiger Länge verschlüsselt werden. Da RSA aber auf der Faktorisierung großer Zahlen beruht, ist es nicht dafür geschaffen große Datenmengen zu verschlüsseln.

andr_gin schrieb:
Da hast du Recht. Gleich lange Datenpakete sind aber in der Praxis ziemlich mühsam. Ich mache das immer so:

Byte 0: Der Typ der Nachricht
Byte 1-4: Die Länger der darauf folgenden Daten in Byte
Byte 5-?: Die Daten

Damit habe ich nicht nur die Länge übertragen, sondern ich weiß auch gleich, was die Bedeutung der Daten ist, die da daher kommen z.B. das Kommando Login oder das Kommando GetFile. Kommt ein Kommando daher, das ich nicht erwartet habe, dann ist die Verbindung asynchron geworden und ich werde eine Exception.

Das ist eine gängige Methode, ja. Kurz und knapp, aber zielführend.

andr_gin schrieb:
Wenn man ausschließlich TCP verwendet, braucht man das gar nicht so kompliziert implementieren. Da reichen mein 5 Byte Header.

Das ist korrekt. Es sollte auch nur als Beispiel dienen. Du hast oben deine eigene Variante vorgestellt, wo du quasi einen 5 Byte Header verwendest. Ob 5 Byte oder wie auf der oben verlinkten Seite 20 Byte interessiert kein Schwein. Das Prinzip ist dasselbe.

Der Vorteil der oben verlinkten Lösung ist das dort eine ereignisorientierte .NET Variante über delegates realisiert wird und sogar der AES selbst implementiert wurde, mit verschiedenen Schlüssellängen.

Das Prinzip sollte dem TE als Orientierung dienen, wie eine gute Lösung auszusehen hat.

andr_gin schrieb:
In den meisten Fällen kommt man mit TCP aus. Man sollte nur TcpClient.NoDelay = True setzen, sonst wird die Verbindung ziemlich zäh, wenn sich die Senderichtung oft ändert und man hat selbst im LAN Latenzen um die 200-500ms.

Die Variante ist nicht unbedingt ratsam. Dazu folgender Absatz:

TCP ist ein Stream (dt. Strom) und sollte auch als kontinuierlicher Datenstrom behandelt werden. Versuchen Sie nicht bei einem NetworkStream die Methode Flush aufzurufen, diese Methode hat keine Wirkung auf einen ungepufferten Netzwerkstrom. Der TCP/IP-Stack im Betriebssystem entscheidet wann und wie Pakete gesendet werden. Grundlage bildet der sogenannte Nagle-Algorithmus. Mit dem Nagle-Algorithmus wird das Versenden von vielen kleinen TCP-Datenpaketen über IP-Netze verhindert. Zu diesem Zweck werden beim Nagle-Mechanismus die kleinen Datenpakete zuerst zwischengespeichert und zu einem größeren Datenpaket zusammen gefasst. Mit dieser Technik soll das Netz von unnötig vielen kleinen Datenpaketen entlastet werden. In Verbindung mit dem Nagle-Algorithmus greift noch ein zweiter Algorithmus, der die Größe des Übertragungsfensters bei der TCP-Verbindung steuert. In der Regel versendet der TCP/IP-Stack ein Segment aus dem TCP-Buffer umgehend nach Ihrem Send-Befehl, doch dafür gibt es weder eine Garantie, noch können oder sollten Sie dieses Verhalten auf der Ebene erzwingen. Unter Windows bewirkt der Nagle-Algorithmus eine Zwischenspeicherung der Pakete am Socket für bis zu 200 Millisekunden. Es ist in .NET möglich die Winsock Option TCP_NODELAY zu setzen und damit den Nagle-Algorithmus zu deaktivieren. Dies wird mit der Eigenschaft Socket.NoDelay erreicht.

http://www.codeplanet.eu/tutorials/csharp/4-tcp-ip-socket-programmierung-in-csharp.html?start=1

Im privaten Netz kannst du TCP_NODELAY setzen, aber ich würde mich in Zukunft nicht darauf verlassen dass das immer so funktionieren wird.

Winsock 2.0, worauf .NET aufbaut, wurde schon in Vista beschnitten, als man die Raw Sockets quasi beerdigte.

Pakete spoofen kannst du seitdem auch nicht mehr ohne Treiber. Und es könnte sein das Microsoft auch mit TCP_NODELAY bald Schluss macht oder zumindest die Funktion abändert.

In den seltensten Fällen muss man den Nagle-Algorithmus deaktivieren. Wenn du viele kleine Pakete hast, dann würde ich gleich UDP nehmen.

TCP_NODELAY benötigt man eigentlich nur bei extrem zeitkritischen Anwendungen, wo in unregelmäigen Abständen sehr kleine Datenpakete transferiert werden.
 
Zuletzt bearbeitet:

Ähnliche Themen

Antworten
11
Aufrufe
2.855
Zurück
Oben