meine Socket Library (Alpha Version)



  • entelechie schrieb:

    so hatte ich das gemeint:

    Socket::SocketLib* instance = 0;
    
    Socket::SocketLib::SocketLib()
    {
    	initSocketLib();
    }
    
    Socket::SocketLib::~SocketLib()
    {
    #ifdef _UNIX_
    	// nothing
    #else
    	WSACleanup();
    #endif
    }
    
    Socket::SocketLib* Socket::SocketLib::GetInstance()
    {
    	static SocketLib socketLib;
    	
    	if ( instance == 0 )
    		instance = &socketLib;
    		
    	return instance;
    }
    
    void Socket::SocketLib::initSocketLib() throw( SocketException )
    {
    #ifdef _UNIX_
    	// nothing
    #else
    	/*
    	 * 0: not initialized
    	 * 1: initialized
    	 * -1: error: could not initialize socket lib (windows only)
    	 */
    	static char initState = 0; // Init: windows only
    	if ( initState == 1 )
    		return;
    		
    	if ( initState == -1 )
    		throw SocketException( "initSocketLib initState -1" );
    	
    	WSADATA wsa;
    	if ( WSAStartup( MAKEWORD( 2, 2 ), &wsa ) == 0 )
    		initState = 1;
    	else
    	{
    		initState = -1;
    		throw SocketException( "initSocketLib WSAStartup != 0" );
    	}
    #endif
    }
    

    und in den header dateien die socket funktionen brauchen
    wird das getinstance aufgerufen:

    namespace
    {
    Socket::SocketLib* socketlib = Socket::SocketLib::GetInstance();
    }

    vielleicht kannst du was damit anfangen.

    Warum initSocketLib()? Du hast doch einen Konstruktor, warum dann noch ne
    extra Memberfunktion dafuer?

    mfg
    v R



  • @Shade
    Hast du dir die Sandkasten-Versionen möglicher Boost-Socket-Libs angeschaut?
    Z.B.
    http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?BoostSocket

    Und was spricht gegen die ACE-Wrapper? Platformübergreifender wird's wohl kaum 🙂



  • @entelechie:

    Naja, ich will nicht unbedingt in allen Klassen das Init aufrufen - das fände ich etwas doof. Und atexit() ist genauso gut wie der dtor eines singletons.

    @Hume:
    ja, angesehen schon. allerdings zielt boost ja nicht gerade darauf ab eine 'easy to use' library zu sein und mein wissen über sockets ist begrenzt 😞

    dh ich kann mit den texten dort nur relativ wenig anfangen - zumal die ja eine 'super duper mega geile' socket library planen. Mir reicht etwas einfaches 🙂

    ACE fällt deshalb weg, weil ich mich damit noch nie näher beschäftigt habe. und ich eigentlich keine große Motivation verspüre neben boost noch eine weiter riesige Library zu verwenden. schon garnicht wenn ich nur einen kleinen teil daraus brauche. und soweit ich sehe, sind ACE Sockets keine streams, oder?



  • Naja, ich will nicht unbedingt in allen Klassen das Init aufrufen - das fände ich etwas doof. Und atexit() ist genauso gut wie der dtor eines singletons.

    nein, das Problem ist, dass atexit nur eine bestimmte Anzahl an Funktionen verwalten können muss. Das sind zwar per Standard unter POSIX mindestens 32 Funktionen, was aber im Endeffekt doch nicht so viel sein kann und es ist bestimmt nicht so leicht rauszufinden, warum das Programm auf einmal nicht mehr so geht wie vorher nur weil irgend wie deine Library dazu gelinkt wurde, vorallem da sich der Fehler ja auf die Komplette Anwendung verteilen kann

    HumeSikkins schrieb:

    Und was spricht gegen die ACE-Wrapper? Platformübergreifender wird's wohl kaum

    ACE ist doch ein riesiger Brocken, vorallem durch die CORBA Funktionen?

    Hab mich aber noch nicht so intensiv mit ACE befasst.



  • Von Volkard kam mal folgender Trick für den WSA-Kram, damit man nichtmehr explizit Init() aufrufen braucht:

    struct SocketInit {
      SocketInit() { WSAInit... };
      ~SocketInit() { WSAClean... };
    };
    
    class Socket {
      Socket()
      {
        static SocketInit sinit; // so hat man den Init-Kram beim ersten Anlegen eines Sockets
                                 // und aufgeräumt wird am Ende des Programms
      }
    };
    

    Und ich finde diese #ifdefs im Code immer schlimm. Würde da um die entsprechenden Teile lieber nochmal Wrapper-Funktionen und -typedefs rumbauen und diese in extra Dateien auslagern.



  • kingruedi schrieb:

    ACE ist doch ein riesiger Brocken, vorallem durch die CORBA Funktionen?

    Die CORBA-Funktionen gehören zu TAO (The ACE ORB) und damit strenggenommen nicht teil der eigentlichen ACE-Lib. Ich meinte allerdings auch nur die ACE-Socket-Wrapper. Das ist nicht so viel. Sind sehr patternlastig. Dafür aber gut dokumentiert.

    und soweit ich sehe, sind ACE Sockets keine streams, oder?

    Es gibt zwar eine ACE_SOCKET_Stream-Klasse, aber die ist kein Stream im iostream-Sinne.



  • DrGreenthumb schrieb:

    Von Volkard kam mal folgender Trick für den WSA-Kram, damit man nichtmehr explizit Init() aufrufen braucht:

    Mein Problem ist aber: ich habe viele verschiedene Klassen in denen Socket-Funktionen sind. Momentan sind es zwar nur Socket und Address, aber da kommen ja noch mehr dazu 😞

    Und ich finde diese #ifdefs im Code immer schlimm. Würde da um die entsprechenden Teile lieber nochmal Wrapper-Funktionen und -typedefs rumbauen und diese in extra Dateien auslagern.

    ich hab lieber #ifdefs im code als code doppelt. Aber ich hab es in der aktuellen version schöner getrennt als in der verlinkten html Datei. Da ist dann alles auch auf mehrere Dateien verteilt.

    @Hume:
    und genau das (keine streams) ist n KO Kriterium für mich.

    Es ist ja weniger dass ich die Socketlib wirklich brauche, es ist eher so, dass ich das als anlass nahm zu sehen ob es wirklich so schwer ist streams zu implementieren wie einige Leute in letzter Zeit im c++ Forum behauptet haben.

    Und ich muss sagen, dank Josuttis STL Buch, ist es nicht wirklich schwer.

    btw: so wie ich es sehe (hab mir ACE mal kurz angeschaut), geht bei ACE die Code-Schönheit aufgrund der absoluten portierbarkeit flöten, oder? Zumindest finde ich den Code nicht wirklich ansprechend (was ich so in den Tutorials gesehen habe).

    Und für mich gibt es eh nur Windows und Linux - andere OS habe ich nicht, lohnt sich also nicht dafür zu programmieren 😉



  • @shade:
    keine der klassen soll das init aufrufen.
    du schreibts die deklaration in eine .cpp datei
    (oder - falls eine statische methode bereits auf die
    socket api zugreift - in die .h datei), damit ist
    sichergestellt, dass die sockets initialisiert sind.

    .h
    namespace
    {
      SocketLib* x = SocketLib::GetInstance();
    }
    
    class Socket
    {
    ...
    }
    


  • du könntest dir mal die socket-funktionen von Qt angucken:
    http://doc.trolltech.com/3.2/qsocket.html

    die sind sehr gut aufgebaut und einfach zu bedienen.

    und wenn du dabei bist guck dir auch QSocketDevice, QHostAddress, QSocketNotifier und Input/Output and Networking an 😉

    da wirst du bestimmt so einige anregungen finden.

    edit: http://doc.trolltech.com/3.2/clientserver-example.html da, ein anwendungsbeispiel.



  • ich finde die CSocket aus der MVC gut, event. kannst du dich ja daran orientieren


Anmelden zum Antworten