2012-10-28 12 views
5

Ich habe einen Client in Java erstellt und möchte einfach einige Daten an meinen Server in C# senden.Client/Server-App - Verlorene Bytes

Das Problem ist, dass wenn ich in den Client zum Beispiel Hallo schreibe, bekomme ich nur den ersten Buchstaben. Im Byte-Array gibt es nur ein Element.

Ich denke, es gibt ein Problem mit der Server-Seite, weil in meinem Server in JAVA alles gut funktioniert, so dass der Client in JAVA gut funktioniert.

Hat jemand ein Problem?

Vielen Dank im Voraus.

+1

Haben Sie debuggen, um herauszufinden, ob k> 1 ist? –

+0

K = 1. Wenn ich es gut bekomme, sollte es sein, wie viele Elemente im Byte-Array sind. Aber da es nur ein Element gibt, k = 1. – Kubik

+0

Versuchen Sie, den Ausgangsstrom nach dem Senden von Daten zu löschen. –

Antwort

2

Problem ist prabably in Java-Seite, weil Ihr Hörer gut funktioniert. Ich kopiere Ihren Listener-Code in eine Testanwendung. Als ich eine andere Testanwendung erstellt und hallo Wort gesendet habe und ich hörte es vollständig.

public static void sender() 
{ 
    TcpClient client = new TcpClient(); 
    IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("192.168.2.236"), 30000); 
    client.Connect(serverEndPoint); 
    NetworkStream clientStream = client.GetStream(); 
    ASCIIEncoding encoder = new ASCIIEncoding(); 
    byte[] buffer = encoder.GetBytes("Hello Server!"); 

    clientStream.Write(buffer, 0, buffer.Length); 
    clientStream.Flush(); 
} 


Connection accepted from 192.168.2.236:22811 
Recieved... 
Hello Server! 

Btw, könnte dies besser Zuhörer sein.

public void listener() 
    { 
    TcpListener tcpListener = new TcpListener(IPAddress.Any, 30000); 
    tcpListener.Start(); 

    TcpClient tcpClient = tcpListener.AcceptTcpClient(); 
    NetworkStream clientStream = tcpClient.GetStream(); 

    byte[] message = new byte[4096]; 
    int bytesRead; 

    while (true) 
    { 
    bytesRead = 0; 

    try 
    { 
     //blocks until a client sends a message 
     bytesRead = clientStream.Read(message, 0, 4096); 
    } 
    catch 
    { 
     //a socket error has occured 
     break; 
    } 

    if (bytesRead == 0) 
    { 
     //the client has disconnected from the server 
     break; 
    } 

    //message has successfully been received 
    ASCIIEncoding encoder = new ASCIIEncoding(); 
    Console.Write(encoder.GetString(message, 0, bytesRead)); 
    } 

    tcpClient.Close(); 
} 
+0

Vielen Dank! Dieser Hörer funktioniert. Auch wenn ich immer noch nicht verstehe, warum die vorherige nicht ging. – Kubik

3

Sie denken über TCP den falschen Weg, Sie nicht einfach "Empfangen" einmal und erhalten das Ergebnis eines "Senden".

TCP ist ein "Streaming" -Protokoll und trennt sich nicht automatisch in "Pakete". Sie können sogar Daten von 2 Sends in einem Empfang erhalten.

Ein gängiges Muster besteht darin, eine Nachricht mit ihrer Länge voranzuzählen, so dass Sie empfangen können, bis Sie die Anzahl der angeforderten Bytes erhalten haben. Um Receive sofort zurückzugeben, wenn sich keine Daten im Puffer befinden, set your socket to non-blocking.

Here's another good article on the topic.

Nun sollte Ihr Code zur Verfügung gestellt oder so arbeiten, weil dort keine Latenz in lokalen Netzwerken nächsten ist. Haben Sie überprüft, ob Ihre Java-Teile Puffer dämpfen/können Sie sie manuell spülen?

3

Als Damon Gant sagte, ist TCP ein Streaming-Protokoll. Ich schlage vor, Sie erstellen Ihr eigenes Protokoll. Ich würde keine Fäden senden. Wenn Sie etwas nicht-Triviales tun, ist dies wirklich der beste Weg zu gehen.

Normalerweise schließe ich eine magische Zahl, Prüfsumme, Paketkörperlänge in Bytes und Protokollversion in meinen Protokollheadern ein. Die magische Zahl erleichtert das Abgrenzen von Paketen in einem Stream (sehr nützlich zum Debuggen Ihres benutzerdefinierten Protokoll-Streams.) Wenn Sie eine Prüfsumme verwenden, können Sie sicherstellen, dass Sie die Dinge korrekt analysieren. Eine Prüfsumme hilft nicht sehr bei der Integrität über TCP, da das TCP-Protokoll bereits eine Prüfsumme hat. Die Paketkörperlänge hilft Ihnen zu erkennen, wenn Sie alle Bytes für Ihr Paket haben. Die Protokollversion kann Ihnen helfen, die Bytes des Paketkörpers zu interpretieren.

Nach dem Empfangen von Daten, legen Sie alle Bytes in einen separaten Puffer und suchen Sie nach Ihrem Protokoll-Header. Wenn Sie Ihre Kopfzeile analysieren können, überprüfen Sie, ob alle Bytes des Pakets vorhanden sind. Wenn ja, parse das Paket. Wiederholen Sie diesen Vorgang, bis Sie ein unvollständiges Paket gefunden haben oder der Puffer leer ist.

Für jedes Paket, das Sie senden möchten, würde ich eine Klasse erstellen. Wenn Sie ein Paket senden möchten, erstellen und serialisieren Sie die richtige Klasse und fügen Sie den Protokollheader für die Bytes dieser Klasse voran.

Sie könnten Javas Serializer verwenden, aber wenn Sie viele Clients mit einem einzelnen Server verbinden, möchten Sie wahrscheinlich nicht Java für den Server verwenden. Dies macht die Sache schwierig, da Sie jetzt einen Java-Serializer in einer anderen Sprache implementieren müssen. Aus diesem Grund ist es in der Regel besser, entweder Ihre Pakete manuell in Bytes umzuwandeln (langwierig, aber einfach) ODER Sie könnten Ihren eigenen Serialisierer mithilfe von Reflektion schreiben. Ich würde Letzteres für größere Projekte vorschlagen.

Verwandte Themen