CAsyncSocket -> Send/Receive



  • hallo C++ Forum
    wieder eine Frage zum leidlichen Thema,

    ich habe eine Klasse geschrieben die 3x CStrings und ein int enthält.
    Bisher habe ich im Send( buffer, buffersize ) nur Strings übertragen und wollte
    jetzt mal eine komplette Klasse übertragen.
    Aber wie?

    ich übergebe im buffer einen Pointer der Klasse den ich vorher mit new() angefordert habe. Mit sizeof(*klasse) hole ich mir die größe.
    der sendbefehl sieht dann so aus:

    CPackage *package = new CPackage;
    package->msg = "hallo"; // msg ist eine von den 3 Stringvariablen
    size_t packsize = sizeof( *package );
    Send( package, packsize );
    

    für Antworten wär ich sehr dankbar da ich schon einiges in Zeit investiert und noch immer keine Lösung gefunden habe 😞



  • class CPackage : public CObject
    {
    DECLARE_SERIAL;
    ...
    };
    
    CSocketFile file( this);
    {
     CArchive ar( &file);
     ar << package;
    }
    


  • danke, werd ich heute abend gleich mal ausprobieren,
    würde mein lösungsansatz auch irgendwie funktionieren oder hab ich
    was grundliegendes falsch gemacht???



  • Im Grundlegenden vielleicht, aber wenn Du Objekte verschickst, muss der Empfänger auch wissen, um was für eines es sich handelt, um aus den Daten dieses erstellen zu können -> dynamische Erstellung.



  • der Empfänger hatte ja auch die klasse, so habe ich im receive den buffer in eine neue klasse kopiert und als buffersize einfach mal 1024 genommen 😉



  • Naja, wenn ich in den Getränkemarkt gehe, möchte ich ja auch, dass auf den Etiketten 'Bitburger', 'Warsteiner' ... draufsteht und nicht einfach nur 'Bier' 😉



  • ^^



  • lol ;)))

    schön anschaulich erklärt *g*
    aber wenn ich eine klasse auf dem server habe
    die ich mit send zum client schicke
    und beim client mit receive die klasse fetche
    und der client ja auch die klasse kennt (zur verfügung hat)

    weiss er ja welches "Bier" es ist oder???



  • warum willst du denn ne ganze klasse verschicken? Da reichen doch die nutzdaten völlig aus.

    also ich mach mir für sowas immer feste structs:

    typedef struct sPackage
    {
        int  cmd;
        char msg[256];
    
    }PACKAGE, *LPPACKAGE;
    

    dann funktionert auch:

    LPPACKAGE package = new PACKAGE;
    strcpy(package->msg,"hallo");
    Send( package, sizeof(PACKAGE) );
    delete package;
    

    CStrings funtionieren da prinzipiell nicht, weil sie nur pointer darstellen, und keine feste speicherbreite haben.

    grüsse



  • 'Kennen'muss der Client die Klasse ja sowieso, sonst könntest Du ja nicht auf Members zurückgreifen.
    Ich habe halt einen Schritt weiter gedacht. Das schöne hieran ist doch, dass jetzt der Bierkenner auch ohne Bierschild auf den Namen des Bieres schliessen kann und auch sofort feststellt, wenn etwas damit nicht stimmen sollte.
    Und auf die 30 oder 40 Byte Datenoffset kommt's ja heutzutage nicht mehr an, oder?

    Weiterhin Codevergleich:

    class CPackage
    {
      CString msg1, msg2, msg3 ...;
    };
    
    // Code funzt
    CSocketFile file( this);
    {
     CArchive ar( &file);
     ar << package;
    }
    
    // folgender Code funzt nicht
    CPackage *package = new CPackage;
    package->msg1 = "hallo"; // msg1 ist eine von den 3 Stringvariablen
    size_t packsize = sizeof( *package );  // Fehler1
    Send( package, packsize );  // Fehler2
    

    -> Die Grössenberechnung und das Senden wird sehr viel komplizierter!



  • @SoUrcerer

    Der Code funzt, hat aber 1. nix mehr mit MFC zutun, und 2. wurden hier 250Byte völlig umsonst verschickt.



  • Korrektur:
    Es ist gar nicht gesagt, dass der Code funzt, denn wenn Send asynchron läuft, ist die Struktur ja gelöscht, bevor sie versendet werden konnte!
    Man müsste also alles mit new anlegen und nicht innerhalb der Funktion wieder löschen.

    [ Dieser Beitrag wurde am 17.03.2003 um 17:02 Uhr von RenéG editiert. ]



  • @RenéG
    richtig, richtig und ähhh richtig.

    Mir ging das auch eigentlich ehr ums prinzip.

    Original erstellt von RenéG:
    -> Die Grössenberechnung und das Senden wird sehr viel komplizierter!

    Kannst du die Lösung mit dem CArchive mal etwas ausführen ... würd mich auch mal interessieren ... Hab damit noch nicht viel gemacht.

    grüsse



  • hmm,

    das ist jetzt auf jedenfall alles schön mal schön und lang erklärt,
    ich druck mir eure beträge jetzt mal aus und diskutiert das heute abend mit
    nem freund von mir, dann versuchen wir mal eine musterlösung zu erstellen.

    werd das dann morgen mal posten



  • Musterlösung 😉

    class CPackage : public CObject
    {
    public:
    DECLARE_SERIAL;  // Dynamisch erstellbar und Daten können per Serialize serialisiert werden
    virtual void Serialize( CArchive& ar);
    CString m_str1, m_str2;
    int i;
    float j;
    };
    
    IMPLEMENT_SERIAL( CPackage, CObject)  // RuntimeClass-Erstellung u.s.w. überlassen wir der MFC
    CPackage::Serialize(...)
    {
      if( ar.IsStoring())
      {
        ar << m_str1 << m_str2 << i << j;
      }
      else
      {
        ar >> m_str1 >> m_str2 >> i >> j;
      }
    }
    
    void CMySocket::Send()
    {
      CSocketFile file( this);
      {
        CArchive ar( &file, CArchive::store);
        ar << package;
      }  // sichergehen, dass ar vor file geschlossen wird
    }
    
    void CMySocket::Receive()
    {
      CSocketFile file( this);
      CArchive ar( &file, CArchive::load);
      {
        CPackage *package;
        ar >> package;  // Erstellung und mit Daten füllen, und alles 'automatisch'
      }  // sichergehen, dass ar vor file geschlossen wird
    }
    

    [ Dieser Beitrag wurde am 17.03.2003 um 17:27 Uhr von RenéG editiert. ]



  • warum verwendest du keine datenkapselung ??du hast die variablen alle als public in deiner class deklariert, das nenne ich nicht musterlösung, *g*



  • Diese unregistrierten Krümelkacker wieder 😉



  • ^^ stimmt



  • das sieht ja nett aus !

    schickes beispiel ... werd ich gleich mal ausprobieren.

    Hast du zufällig noch parat, wie man einen rohen byte puffer mit bekannter länge mit CArchive streamen kann ?? Muss ich mir das sowas schreiben, wie CRawBytes und da Serialize überladen etc. ? oder kann CByteArray (aus mfc) das schon von haus aus?

    grüsse



  • Stell Dir vor, was in der MSDN steht, wenn man sie liest:

    CByteArray incorporates the IMPLEMENT_SERIAL macro to support serialization and dumping of its elements. If an array of bytes is stored to an archive, either with the overloaded insertion (<< ) operator or with the Serialize member function, each element is, in turn, serialized.


Anmelden zum Antworten