Frage: 6. Arg bei recvfrom()/sendto() ?



  • Ähm, die Größem, die im 6. Argument gemeint ist, hat mit dem Datenpuffer gar nichts zu tun. das Argument beschreibt die größe der sockaddr*-Struktur die die Adresse angibt. (Je nachdem, welche IP-Familie du nutzt)

    Beri recvfrom ist das Argument zusammen mit dem 5. Argument optional. Der Wert kann sich aber auch verändern. (Bspw. wenn du als 5. Argument ne sockaddr_in6 übergibst, aber die Quelle eine sockaddr_in ist)

    Bei sendto müsste das argument konstant bleiben - dort ist es aber auch notwendig also nicht optional.

    Was genau ist das Problem? 🙂

    Lg,
    SALOMON



  • OK, Danke, das war für das Verständnis schon einmal hilfreich. Klar - Es gibt eben verschiedene Adresstypen.

    Aber das hieße ja das wäre Vererbung in C? Wie sieht das intern aus?



  • int sendto(..., const sockaddr *addr,...)
    {
        int addr_familiy = GetAddrFamily(soc);
        if (addr_family == AF_INET)
        {
            const sockaddr_in *paddr_in = (const sockaddr_in *)addr;
            _k_sendto(..., paddr,...);
        }
        else
        {
            // ....
            _k_sendto(...);
        }
    }
    


  • (const sockaddr_in *)addr
    

    Was passiert hier?



  • der zeiger auf die "basisklasse"

    const sockaddr *
    

    wird in die "abgeleitete" klasse

    const sockaddr_in *
    

    gecastet.

    der typ wird vorher über die address-familiy ermittelt.



  • OK, aber es ist ja kein C++-Prog - also gibt es keine Klassen und Vererbung. Von daher verstehe ich nicht, wie so etwas in C realisiert werden kann.



  • Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum ANSI C verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • ganz einfach, in C++ wird anhand des zeigers auf die vtbl die richtige
    funktion ausgewählt.

    class base
    {
    public:
        virtual void funktion() = 0;
    };
    class derived1 : base
    {
    public:
        void funktion(){}
    }
    class derived2 : base
    {
    public:
        void funktion(){}
    }
    int main()
    {
        derived1 d1;
        derived2 d2;
        base *b = &d1;
        b->funktion();
        b = &d2;
        b->funktion;
    }
    

    kann man in c ebenso machen:

    void base_funktion(){*(int *)0; /* fehler produzieren, da purevirtual */}
    void derived1_funktion(){}
    void derived2_funktion(){}
    typedef void (*pfunc)();
    
    struct base
    {
        pfunc func;
    }
    struct derived1
    {
        pfunc func;
    };
    struct derived2
    {
        pfunc func;
    };
    void base_ctor(base *b)
    {
        b->func = base_funktion;
    }
    void derived1_ctor(derived1 *d)
    {
        d->func = derived1_funktion;
    }
    void derived2_ctor(derived1 *d)
    {
        d->func = derived2_funktion;
    }
    int main()
    {
        derived1 d1;
        derived1_ctor(&d1);
        derived2_d2;
        derived2_ctor(&d2);
        base *b = &d1;
        b->func();
        b = &d2;
        b->func();
    }
    

    ist zwar ne frickelei aber es geht. z.b. gibt es com-interfaces auch im
    c-stil.



  • sockaddr ist auch keine Klasse sondern eine Struktur. sockaddr_in ist eine Weiterentwicklung davon. Das sieht dann ungefähr so aus:

    struct sockaddr_in
    {
        sockaddr addr;
        .... weiterer Code
    }
    

    Fakt ist, dass du gar nicht wissen brauchst, um was für eine sockaddr handelt, wenn du die richtige Größe dazu hast 😉



  • Hey prima das hat mir geholfen! Vielen Dank 🙂


Anmelden zum Antworten