ver und ent-casting von strukturen für sockets



  • Hallo,

    Problem:
    ich habe ein Problem beim casten, ich weiss was ich in etwa machen will, ich weiss nur nicht wie ich es in anständige c++ syntax formulieren kann.

    Was geht:
    Ich benutze die SDL_NET sockets, um Daten per TCP zu senden. Ich kann einen type/struct das mir bekannt ist casten und senden, da ich weiss was ich auf der anderen seite erwarte kann ich es auch zurück casten.

    int Data = 100;   // kann alles an daten sein
    SDLNet_TCP_Send(sock_server, &Data, sizeof(Data));
    

    Ich Möchte:
    Ich möchte nun verschiedene datentypen (struct'e) senden und auf der anderen seite erkennen können was das ist, und dann dementscprechend zurück casten, deshalb dachte ich verpacke ich die stucte ersteinmal in ein Packet: z.B:

    struct _DatenPacket{
    	int type;     // Zahl die sagt was für struct drinnen steckt
    	int len;      // prüfsumme für das struct
    	void *data;   // struct selber
    };
    

    Was Ich schon versucht habe:
    - Tagelang gegooglet, keine anfänger freundlichen Tutorials gefunden.
    - Stundenlang www.koders.com Quellcodes gelesen von Programmen, Spielen usw die in etwa das machen, aber nicht wirklich verstanden.
    - Bücher gewälzt über cast, typen, zeiger usw. auch verstanden, aber beim zusammenfügen (syntax) komm ich nicht weiter
    - Versuche das Ergebnis byteweise auseinander zu nehmen (um zumindest den int(type) wert zu lesen), dann aber mit irgendwelchen speicher Fehlern hängen geblieben

    Was hilfreich wäre:
    - Ideen wo ich hilfe zur selbsthilfe finde, auch gerne google nach: XYZ
    - Links zu brauchbaren SDL_NET Tutorials (es gibt da echt wenig ausser die standart referenz)
    - Jemanden der zufällig die Lösung hat die ich auch verstehe 🙂

    Sorry das ist mein erster Post, ich hoffe es ist alles so übersichtlich, einen kompletten Sourcecode habe ich nicht, nur einzelteile aus verschiedenen quellen ausser vieleich die versende funktion, ich bekomme die nur nicht wieder auseinander:

    void myNetworkClient::sendData( void *data, int len ) {
    	if(!sock_server) printf("sendData: Socket nicht OK\n");
    	if (!data || len < 1) printf("sendData: Daten sind leer\n");
    	int lenErgebnis = SDLNet_TCP_Send(sock_server,data,len);
    	if lenErgebnis < len) printf("sendData: Problem beim senden\n");
    }
    

    Grüsse
    xuedi



    Ich kenn mich mit newörkkram selber nich so aus... aber wenn du ein Objekt aufm speicher allokierst, und den zeiger auf das Objekt in ein void* Zeiger castest, diesen übers netzt jagst, hast du auf der anderen seite ein Zeiger, aber wo ist da das objekt;) Der empfänger hat sicher einen eigenen Heap;) also muss das das objekt selber übertragen.... oder serielisieren.. kein plan

    Wenn du ein objekt XYZ bzw. desen zeiger auf ein void zeiger castest, wei der PC nachher nicht mehr um was für ein Objekt es sich handelt, der Objektname steht ja nich im zeiger, der zeiger ist ja nur die Adresse wo das objekt liegt..

    Wie sehen die structs aus die du senden möchtest?



  • die versende funktion, ich bekomme die nur nicht wieder auseinander:

    Na, du castest zuerst nach _DatenPacket und dann nen switch über type und data entsprechend casten.


  • Mod

    Typ und Länge müssen natürlich auch mit versendet werden, um die Daten nach dem Empfang restaurieren zu können. ganz grob:

    void myNetworkClient::sendData( const DatenPacket& data, int len ) {
        if( !sock_server ) { printf( "sendData: Socket nicht OK\n" ); return; }
        if ( !data || data.len < 1 )  7 printf( "sendData: Daten sind leer\n" ); return; }
        if ( SDLNet_TCP_Send( sock_server, &data.type, sizeof data.type ) < sizeof data.type
          || SDLNet_TCP_Send( sock_server, &data.type, sizeof data.len ) < sizeof data.len
          || SDLNet_TCP_Send( sock_server, data.data, len ) < len )
            printf("sendData: Problem beim senden\n");
    }
    
    void myNetworkClient::recvData( DatenPacket& data, int len ) {
        if( !sock_server ) { printf( "recvData: Socket nicht OK\n" ); return; }
        if ( SDLNet_TCP_Recv( sock_server, &data.type, sizeof data.type ) == sizeof data.type
          && SDLNet_TCP_Recv( sock_server, &data.len, sizeof data.len ) == sizeof data.len
          && data.len > 0 )
        {
            data.data = new char[ data.len ];
            if ( SDLNet_TCP_Recv( sock_server, data.data, data.len ) == data.len )
                return;
            delete [] data.data;
            data.data = 0;
        }
        data.len = 0;
        data.type = 0;
        printf("recvData: Problem beim Empfang\n");
    }
    

    Die Interpretation von DatenPacket muss dann der Aufrufer übernehmen; das könnte eine Factory sein.



  • wow,

    vielen Dank für die schnellen und interesannten Antworten, ich denke ich weiss jetzt wo ich weiter muss, super Forum!

    grüsse
    xuedi


Anmelden zum Antworten