Laden...

Wie kann man der Stream.Read() Methode am besten prüfen lassen, ob es die richtigen Daten sind?

Erstellt von Drake vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.843 Views
D
Drake Themenstarter:in
10 Beiträge seit 2019
vor 4 Jahren
Wie kann man der Stream.Read() Methode am besten prüfen lassen, ob es die richtigen Daten sind?

Guten Abend liebe Community,
ich habe vor, ein kleines Spiel zu programmieren in C#, die Basis steht auch schon. Da die System.Net.Sockets Klasse für mich noch Neuland ist, habe ich eine Frage zur Koordination. Achso ich sollte eventuell erwähnen das die Verbindung schon steht und das ganze über TCP gehen muss, da keine Daten verloren gehen dürfen.

Also meine Frage ist, wie kann man dem Stream bei der Read Methode am besten prüfen lassen, ob es die richtigen Daten sind? Ich habe das Problem, das ich am Anfang dem Server den Spielernamen des Clients sende, aber im Clienten direkt die Anzahl der mit dem Server verbundenen Clients mit auf den Weg gebe. Jetzt kommt es am Anfang immer dazu, dass bei der Ausgabe der Anzahl der Spieler die Bits des ASCII Code von dem Usernamen in der Variable vom Spielecounter laden.

Wie kann man jetzt gewisse Daten speichern beim Clienten wenn vom Server über mehrere Stream.Write verschiedene Daten kommen.

Mein Gedanke wäre jetzt eine Art ID als ersten Bit zu speichern und so die Daten eindeutig zuzuordnen und dann via switch/case oder whatever weiterzuverarbeiten. Aber gibt es da eine performantere Alternative. Ich habe schon etwas von beginWrite/Read und asynchroner Übertragung gehört, habe aber die Beispiele nicht ganz verstanden.


// Client verbindet sich mit dem Server
                clientSocket.Connect("192.168.178.23", 8888);
                serverStream = clientSocket.GetStream();

                byte[] outStream = System.Text.Encoding.ASCII.GetBytes(settings.getUsername() + "$");
                serverStream.Write(outStream, 0, outStream.Length);
                serverStream.Flush();

// Löst einen Timer aus der dann folgendes tut..
// Er fragt die ganze Zeit wie viele Spieler verbunden sind, hier kommt es dann dazu das von oben der Username einmal zum Start fälschlicherweise ausgegeben wird, ist ja auch kein Wunder der Server ist ja keine KI und weiß, welche Daten ich haben will.

            byte[] bytes = new byte[10025];
            stream.Read(bytes, 0, bytes.Length);

            this.playerCount = bytes[0]; // Hier die Falschen Daten

// Zudem schreibt der Client immer zum Server, damit dieser weiß, dass der Client noch da ist. Da werden sich die Streams vermutlich auch in die Quere kommen.

Ich hoffe der Ausschnitt reicht aus, um zu zeigen, was ich meine. Ansonsten kann ich den Code nochmal ausführlich mit allen Methoden schicken.

Also wie kann man jetzt alles auslesen, mit dem Hintergrund immer alle richtigen Daten für jeden Read Aufruf zu bekommen.

Entschuldigung für den langen Text, schreibe aber immer gerne, welche Gedankengänge ich gerade verfolge.

P
441 Beiträge seit 2014
vor 4 Jahren

Hi,

mach es dir nicht zu schwer. Es gibt bereits fertige Frameworks und Protokolle, die genau das bieten.
In der Regel ist es weder ratsam noch notwendig ein eigenes Protokoll zu entwickeln (Selbstschulung und Verständnis ausgenommen).

Je nachdem, was du vorhast würde sich gRPC (mit .NET Core 3.0) oder z.B. auch MQTT anbieten.

D
Drake Themenstarter:in
10 Beiträge seit 2019
vor 4 Jahren

Erstmal vielen Dank für deine Antwort, ich habe mir beide Frameworks angeschaut und bin seit Tagen dran, diese zu verstehen ..

Hi,

mach es dir nicht zu schwer. Es gibt bereits fertige Frameworks und Protokolle, die genau das bieten.

Ich habe das Gefühl, das meine Methode einfacher ist, anstatt eine der beiden Frameworks zu verwenden.

Bei der MQTT Framework habe ich bis heute kein brauchbares Beispiel gefunden und im Wiki lese ich immer nur Sachen von Android.

Bei gRpc habe ich auch noch nicht durchgebickt.


// Beispiel der Seite für den Server
class GreeterImpl : Greeter.GreeterBase
{
    // Server side handler of the SayHello RPC
    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
    }

    // Server side handler for the SayHelloAgain RPC
    public override Task<HelloReply> SayHelloAgain(HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply { Message = "Hello again " + request.Name });
    }
}

// Beispiel der Seite für den Client

public static void Main(string[] args)
{
    Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);

    var client = new Greeter.GreeterClient(channel);
    String user = "you";

    var reply = client.SayHello(new HelloRequest { Name = user }); // SayHello wird nicht gefunden, ist auch kein Wunder,da ich keine Klasse finden konnte in der diese Methode definiert wurde, die Framework ist eingebunden via Nuget Manager.
    Console.WriteLine("Greeting: " + reply.Message);
    
    var secondReply = client.SayHelloAgain(new HelloRequest { Name = user });
    Console.WriteLine("Greeting: " + secondReply.Message);

    channel.ShutdownAsync().Wait();
    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();
}


In dem Beispiel von der Github Seite, welches ich heruntergeladen habe, wird das nicht rot unterstrichen. Allerdings konnte ich in dem Beispiel Projektordner auch keine anderen Klassen finden in denen dieser Name vorkommt. Ich bin seit ein paar Tagen sehr frustriert.

4.931 Beiträge seit 2008
vor 4 Jahren

gRPC beruht auf ".proto"-Dateien (woraus dann Code erzeugt wird). Hast du denn die helloworld.proto bei dir im Projekt eingebunden (s. gRPC services with C#)?

D
Drake Themenstarter:in
10 Beiträge seit 2019
vor 4 Jahren

Hast du denn die
>
bei dir im Projekt eingebunden (s.
>
)?

Ja, die Datei ist im Projekt enthalten (s. Screen.)

D
Drake Themenstarter:in
10 Beiträge seit 2019
vor 4 Jahren

Auf dem Screen unter der Zeile ist die Frage , in welche Datei müssen die XML Zeilen eingefügt werden?

P
441 Beiträge seit 2014
vor 4 Jahren

Die XML ist die csproj Datei. Lad dir am besten das Beispielprogramm und probier es aus.

D
Drake Themenstarter:in
10 Beiträge seit 2019
vor 4 Jahren

So das ganze hat jetzt geklappt mit der gRPC Framework, danke erstmal 😄, also das Beispiel, dass der Client ein String zum Server schickt und dieser die dann wieder zum Clienten schickt. Nun, dass hilft mir für das Projekt nur semi weiter. Der Server soll ja Daten an den Clienten schicken. Jetzt habe ich das Beispiel vom RouteGuide gefunden, nur leider klappt der Beispielcode nicht mal im Beispiel selbst. Ich habe gelesen, das es eine Variante gibt, dass der Client eine Sache an den Server schickt und der Server dann über den Stream, der mitgeschickt wird, Sachen versenden kann. Mein gedanke wäre dann, in iner Whileschleife meine Daten zu verschicken, die permanent aktualisiert werden müssen. Allerdings kann man asynchrone Methoden nur in einer Asnchronen Methode aufrufen. Da ich jetzt testweise ein Win-Form erstellt habe, gammelt der halbe Code im Construktor vom Form rum(Nicht schön, ich weiß aber ist ja auch nur zum lernen 😉). Sitze jetzt mehrere Stunden dran, die Beispiele der Seite sind teils grausam. Und wie ich gesehen habe gibt es auch keine Broadcast Funktion seitens des Servers. Was kann man da machen?