send / recv ohne char



  • wird mir hierbei eine korrekte Klasse zurückgeliefert? (bei recv)

    bool User::Send (message & msg) const
    {
        if (!msg.validate())
        {
            throw xBadBuffer ();
            return false;
        }
    
        if ( send (itsSock, (char *) &msg, sizeof(msg), 0) == SOCKET_ERROR)
        {
            throw xSendFailed ();
            return false;
        }
    
        return true;
    }
    
    message User::Recv () const
    {
        message msg;
    
        if ( recv (itsSock, (char *) &msg, msg.GetMaxSize(), 0) == SOCKET_ERROR)
        {
            throw xRecvFailed ();
        }
    
        return msg; // ist das hier ne Klasse oder nur Datenmüll?
    }
    


  • Ne Klasse.
    Weil der Rückgabewert vom Typ message ist wird eine Kopie angelegt und zurückgegeben.



  • ne, ich hab das anders gemeint. ist das message-objekt kaputt, oder nicht lesbar, dadurch dass ich zweimal nach (char 😉 gecastet habe?



  • IMHO nicht.



  • Du darfst aber nicht vergessen, dass Zeiger in der Klasse dadurch ungültig werden. D.h. mit einer Klasse wie std::string wird soetwas garantiert nicht klappen.



  • wie kann ich das dann machen?
    ich will auf jeden fall eine Klasse senden!
    bisher sieht die so aus:

    #include <string>
    
    #ifndef MESSAGE_HPP
    #define MESSAGE_HPP
    
    /*------------------- Allgemeine Messages ------------------------------------*/
    #define     NOTHING                         9999
    
    /*------------------- Messages von Client ------------------------------------*/
    #define     CLOSE                           1001
    #define     NAME                            1002
    #define     CLIENTTXT                       1004
    
    /*------------------- Messages vom Host --------------------------------------*/
    #define     KICK                            1003
    #define     HOSTTXT                         1005
    #define     REMARK                          1006
    #define     RECVD                           1007
    
    /*------------------- Maximalwerte für Messages ------------------------------*/
    #define     MAX_BUFFER_SIZE                 1020
    #define     MAX_NAME_SIZE                   80
    
    using std::string;
    
    class Message
    {
        public:
        Message (): TypeOfMsg (NOTHING) {}
        Message (const Message & rhs): TypeOfMsg (rhs.TypeOfMsg), NameOfSender (rhs.NameOfSender), MsgText (rhs.MsgText) {}
        ~Message () {}
    
        bool validate () const;
        unsigned short int GetMaxSize () const { return (MAX_BUFFER_SIZE + MAX_NAME_SIZE + 2); }
    
        unsigned short TypeOfMsg;
        string NameOfSender;
        string MsgText;
    };
    
    #endif
    


  • k, hab jetz alle strings in char-arrays umgewandelt.
    problem ist, es kommt immer noch sch*** an!
    wie bekomm ich bei recv() eine korrekte Klasse?



  • char-Arrays sind doch Zeiger. Und das geht nicht.

    Nimm doch einen std::stringstream und gib ihn der Klasse. Die Klasse schreibt ihre Variablen dann irgendwie darein (z.B. nacheinander, mit einem Code vorne damit man die wieder auseinanderkriegt). Diesen stringstream schickst du dann weg, indem du ihn in char* umwandelst:

    std::ostringstream stream;
    msg.save(stream);
    string = stream.str();
    send(sock, string.c_str(), string.length() + 1)
    

    In der Funktion save der Klasse message werden die Variablen einfach in den Stream geschrieben. Das geht genauso wie mit cout.

    edit:
    Edler wäre folgendes anstelle msg.save:

    stream << msg;
    


  • so?:
    (das erzeugt bei mir aber irgendwie nen runtime-error!)

    void Message::load (char * cstr, int size)
    {
        // Typ der Nachricht -------------------------------------------------------
        char buf[81];
        for (short i=0; i < 5; i++)
            buf[i] = cstr[i];
        TypeOfMsg = atoi (buf);
    
        // Name des Absenders ------------------------------------------------------
        for (short i=5; i < 80; i++)
            buf[i-5] = cstr[i];
        NameOfSender = buf;
    
        // Nachricht ---------------------------------------------------------------
        char buffer[size - 80];
        for (short i=80; i < size; i++)
            buffer[i-80] = cstr[i];
        MsgText = buffer;
    }
    
    char * Message::store ()
    {
        char * buffer = new char [5+MAX_NAME_SIZE+MAX_BUFFER_SIZE];
    
        // Type nach String --------------------------------------------------------
        char * buf = new char[10];
        sprintf (buf, "%d", TypeOfMsg);
        for (short i=0; i < 5; i++)
            buffer[i] = buf[i];
        delete buf;
    
        // Name --------------------------------------------------------------------
        buf = new char[80];
        strcpy (buf, NameOfSender.c_str ());
        for (short i=NameOfSender.size(); i < 80; i++)
            buf[i] = ' ';
        for (short i=0; i < 80; i++)
            buffer[i+5] = buf[i];
        delete buf;
    
        // Nachricht ---------------------------------------------------------------
        buf = new char[MsgText.size()];
        strcpy (buf, MsgText.c_str());
        for (short i=0; i < 5+MAX_NAME_SIZE+MsgText.size(); i++)
            buffer[i+85] = buf[i];
        delete buf;
    
        return buffer;
    }
    


  • Warum nimmst du keinen std::stringstream?
    store() gibt einen mit new allozierten Speicherblock zurück; böse, böse.

    Hast du das mal gedebuggt und nachgeschaut, was store() wirklich zurückliefert?

    btw, etwas OT:
    Nimm int und nicht short. short ist auf heutigen CPUs immer langsamer als int, gerade weil es kleiner ist.



  • weil ich davon nicht wirklich viel ahnung hab


Anmelden zum Antworten