Ergebnis 1 bis 3 von 3

Thema: Client-Server-Model

  1. #1
    Neuer Benutzer
    Registriert seit
    18.10.2007
    Beiträge
    2

    Standard Client-Server-Model

    Hallo, ich möchte ein großes Datenpaket mittels TCP/IP übertragen.

    Ich benutze das Client-Server-Model des hier beschriebenen Tutorials.

    http://www.codeplanet.eu/tutorials/c...er-modell.html

    Serverseitig:

    Code:
            public void SendMusiktitelListe(IPacket packet)
            {
                LogConsole("asked for Musiktitellist. Sending.", packet.Source);
                Encoding enc = Encoding.Unicode;
                IPacket replyPacket = Protocol.CreatePacket(SocketType.Stream);
                replyPacket.Type = PacketType.MusiktitelListeReply;
                replyPacket.Encoding = enc;
                replyPacket.Source = ServerIPEndPoint;
                replyPacket.Destination = packet.Source;
                byte[] data = SerializeMusiktitelListe(enc);      // Das komplette Paket
    
                // zerteile das ganze Paket in kleinere mit 1500Bytes.
                byte[] myWriteBuffer = new byte[Vars.MTU];
                int index = 0;
    
                // a = source array
                // 1 = start index in source array
                // b = destination array
                // 0 = start index in destination array
                // 3 = elements to copy
                // Array.Copy(a, 1, b, 0, 3);
    
                while ((index + Vars.MTU) < data.Length)
                {
                    Array.Copy(data, index, myWriteBuffer, 0, Vars.MTU);    // MTU = 1500
                    replyPacket.Data = myWriteBuffer;
                    Send(replyPacket);
                    index += Vars.MTU;
    
                    Thread.Sleep(100);     // meiner Verzweiflung geschuldet! Hilft nicht!
                };
    
                if (index < data.Length)
                {
                    myWriteBuffer = new byte[data.Length - index];
                    Array.Copy(data, index, myWriteBuffer, 0, data.Length - index);
                    replyPacket.Data = myWriteBuffer;
                    Send(replyPacket);
                }
            }
    Clientseitig:

    Code:
    /// <summary>
    /// Stores all possible packet types in the protocol.
    /// </summary>
    public void PacketReceived(object sender, PacketEventArgs e)
    {
        // Switch on message types
        switch(e.Packet.Type)
        {
            case PaketType MusiktitelListeResponse:
                UpdateMusiktitelListe(e.Paket);
                break;
            ...
        }
    }
    Code:
            List<string> datenPakete = new List<string>();
    
            private void UpdateMusiktitelListe(IPacket packet)
            {
                try
                {
                    Encoding enc = packet.Encoding;
                    string data = enc.GetString(packet.Data);
    
                    datenPakete.Add(data);
    
                    // Alle Pakete bis EOF lesen
                    if (data.EndsWith(Vars.EOF) == true)
                    {
                        sbMusiktitelListe = new StringBuilder();
    
                        foreach(string s in datenPakete)
                            sbMusiktitelListe.Append(s);
    
                        datenPakete.Clear();
    
                        MusiktitelListe = sbMusiktitelListe.ToString();
    
                        if (GetMusiktitelListe != null)
                            GetMusiktitelListe();                    
    
                        SendStatus(">>> Update MusiktitelListe <<<");
                    }
                } <----------- Breakpoint
                catch (ArgumentNullException ex)
                {
                    SendStatus(ex.Message);
                }
            }
    Die Verbindung zum Server wird unterbrochen und das Paket kommt unvollständig an.
    Wenn ich den Client Debugge ist alles OK.

    Wer kann hier weiterhelfen?

    Schon mal ein Danke im voraus.

    Outdoorboy

  2. #2
    CodePlanet Staff Avatar von StarShaper
    Registriert seit
    10.09.2005
    Beiträge
    45

    Standard

    Zitat Zitat von outdoorboy Beitrag anzeigen
    Die Verbindung zum Server wird unterbrochen und das Paket kommt unvollständig an.
    Hallo.

    Wie lautet die Fehlermeldung bzw. die Meldung der Exception?

  3. #3
    Neuer Benutzer
    Registriert seit
    18.10.2007
    Beiträge
    2

    Standard

    Hallo.

    Ich habe den Code noch einwenig modifiziert. Die Trennung mit MTU ist für das Datenpaket
    Clientseitig nicht günstig. Somit erhalte ich jetzt immer ein Datenpaket das in sich Konsistent ist.

    Server:
    PHP-Code:
            public void SendMusiktitelListe(IPacket packet)
            {
                
    LogConsole("asked for Musiktitellist. Sending."packet.Source);
                
    Encoding enc Encoding.Unicode;
                
    IPacket replyPacket Protocol.CreatePacket(SocketType.Stream);
                
    replyPacket.Type PacketType.MusiktitelListeReply;
                
    replyPacket.Encoding enc;
                
    replyPacket.Source ServerIPEndPoint;
                
    replyPacket.Destination packet.Source;
                List<
    byte[]> data SerializeMusiktitelListe(enc);

                foreach(
    byte[] bts in data)
                {
                    
    replyPacket.Data bts;
                    
    Send(replyPacket);
                }
            } 
    Client:
    PHP-Code:
            List<stringdatenPakete = new List<string>();

            private 
    void UpdateMusiktitelListe(IPacket packet)
            {
                try
                {
                    
    Encoding enc packet.Encoding;
                    
    string data enc.GetString(packet.Data);

                    
    // Das Datenpaket verarbeiten Titel zur Liste hinzufügen
                    
    MusiktitelListe data;

                    if (
    GetMusiktitelListe != null)
                        
    GetMusiktitelListe();                    

                    
    SendStatus(">>> Update MusiktitelListe <<<");
                }
                catch (
    ArgumentNullException ex)
                {
                    
    SendStatus(ex.Message);
                }
            } 
    Client:
    Methode ReceivePaketFromServer() führt zur Client Fehlermeldung:
    Code:
    "Der Vorgang ist für nicht blockierende Sockets unzulässig."
    ClientStatus: Lost connection to server!

    Server Debug oder Run Modus:
    Der Fehler ist nicht reproduzierbar. Folgende 3 Meldungen kommen immer unterschiedlich.
    Methode ReceivePacketFromClient() führt zu Server Fehlermeldung:
    Code:
    "Der Vorgang ist für nicht verbundene Sockets unzulässig."
    "Von der Übertragungsverbindung können keine Daten gelesen werden: Eine vorhandene Verbindung wurde vom Remotehost geschlossen."
    "Ein nicht blockierender Socketvorgang konnte nicht sofort ausgeführt werden."
    ServerStatus: Disconnected

    Die obigen Methoden funktionieren wenn nur ein Datenpaket gesendet wird und dieses eine bestimmte Größe nicht überschreitet.
    Der von mir gemessene Wert liegt bei ca 700 für byte[].Length. Größer führt zu obigen Fehlern. Der erfolgreiche Datenverkehr hängt
    von der Größe des Datenpakets ab(Meine Erfahrung). Der Fehler ist aber nicht reproduzierbar. Mehrere Client spielen für den Datenverkehr
    keine Rolle.

    Das zu übertragende Datenpaket wird hiermit zestückelt.
    PHP-Code:
            List<byte[]> paketsToSendList = new List<byte[]>();

            private List<
    byte[]> SerializeMusiktitelListe(Encoding encoding)
            {
                
    paketsToSendList.Clear();
                
    string liste CreateMusiktitelListe();
                
    string[] sa liste.Split(new string[] { Vars.DELIMITER }, StringSplitOptions.None);
                
    string data "";

                foreach (
    string s in sa)
                {
                    
    data data Vars.DELIMITER;

                    if (
    data.Length 360)
                    {
                        
    paketsToSendList.Add(encoding.GetBytes(data));
                        
    data "";
                    }
                }

                if (
    data != "")
                {
                    
    data data.Remove(data.Length 55);     // letzten Deliniter löschen
                    
    paketsToSendList.Add(encoding.GetBytes(data));
                }

                return 
    paketsToSendList;
            } 
    Die letzen Versuche ergaben bei langen Listen und zerstückelten Datenpaketen um 400 Bytes zu 90%
    einen vorzeitigeb Abbruch.

    Somit ergibt sich die Frage "Wie versende ich die einzelnen Pakete" um einen sicheren Datenverkehr und keinen Abbruch der Verbindung zu bekommen.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •