WinSock Problem



  • Schreibe grad ne kleine WinSock Anwendung und habe folgendes Problem, ich deaktiviere die DEFAULTLIBRARIES und lade die WinSock Funktionen zur Laufzeit. Ich zeige einfach erstmal den Quelltext:

    #include <winsock2.h>
    #include <windows.h>
    
    typedef int	(*PFNWSASTARTUP)(WORD, LPWSADATA);
    typedef SOCKET  (*PFNSOCKET)(int, int, int);
    typedef int	(*PFNCLOSESOCKET)(SOCKET);
    typedef int	(*PFNBIND)(SOCKET, const SOCKADDR*, int);
    typedef int     (*PFNLISTEN)(SOCKET, int);
    typedef SOCKET  (*PFNACCEPT)(SOCKET, SOCKADDR*, int*);
    typedef int	(*PFNSEND)(SOCKET, const char*, int, int);
    typedef int	(*PFNRECV)(SOCKET, char*, int, int);
    typedef u_short (*PFNHTONS)(u_short);
    typedef u_long  (*PFNHTONL)(u_long);
    typedef int	(*PFNWSAGETLASTERROR)(void);
    
    static PFNWSASTARTUP      pfnWSAStartup   = 0;
    static PFNSOCKET          pfnSocket       = 0;
    static PFNCLOSESOCKET     pfnCloseSocket  = 0;
    static PFNBIND		  pfnBind	  = 0;
    static PFNLISTEN	  pfnListen	  = 0;
    static PFNACCEPT	  pfnAccept	  = 0;
    static PFNSEND		  pfnSend         = 0;
    static PFNRECV		  pfnRecv         = 0;
    static PFNHTONS	          pfnHtons	  = 0;
    static PFNHTONL		  pfnHtonl        = 0;
    static PFNWSAGETLASTERROR pfnGetLastError = 0;
    
    int __cdecl WinMainCRTStartup() {
    
    	HMODULE hWinSock = LoadLibrary(L"Ws2_32.dll");
    	if(!hWinSock) return 1;
    
    	pfnWSAStartup   =
    reinterpret_cast<PFNWSASTARTUP>(GetProcAddress(hWinSock,"WSAStartup"));
    	pfnSocket       = reinterpret_cast<PFNSOCKET>(GetProcAddress(hWinSock, "socket"));
    	pfnCloseSocket  = reinterpret_cast<PFNCLOSESOCKET>(GetProcAddress(hWinSock, "closesocket"));
    	pfnBind	        = reinterpret_cast<PFNBIND>(GetProcAddress(hWinSock, "bind"));
    	pfnListen	    = reinterpret_cast<PFNLISTEN>(GetProcAddress(hWinSock, "listen"));
    	pfnAccept       = reinterpret_cast<PFNACCEPT>(GetProcAddress(hWinSock, "accept"));
    	pfnSend		    = reinterpret_cast<PFNSEND>(GetProcAddress(hWinSock, "send"));
    	pfnRecv		    = reinterpret_cast<PFNRECV>(GetProcAddress(hWinSock, "recv"));
    	pfnHtons	    = reinterpret_cast<PFNHTONS>(GetProcAddress(hWinSock, "htons"));
    	pfnHtonl	    = reinterpret_cast<PFNHTONL>(GetProcAddress(hWinSock, "htonl"));
    	pfnGetLastError = reinterpret_cast<PFNWSAGETLASTERROR>(GetProcAddress(hWinSock, "WSAGetLastError"));
    
    	WSAData sData;
    	if(pfnWSAStartup(MAKEWORD(2, 2), &sData)) return 1;
    
    	SOCKET iListenSocket = pfnSocket(AF_INET,
    					 SOCK_STREAM,
    					 IPPROTO_TCP);
    
    	if(iListenSocket == INVALID_SOCKET) return 1;
    
    	SOCKADDR_IN sSockAddr;
    	sSockAddr.sin_addr.s_addr = INADDR_ANY;
    	sSockAddr.sin_family	  = AF_INET;
    	sSockAddr.sin_port	  = pfnHtons(12532);
    
    	if(pfnBind(iListenSocket,
    		   reinterpret_cast<SOCKADDR*>(&sSockAddr),
    		   sizeof(sSockAddr)) == SOCKET_ERROR) return 1;
    
    	int iLength = sizeof(sSockAddr);
    
    	MSG msg;
    	while(GetMessage(&msg, 0, 0, 0)) {
    
    		if(pfnListen(iListenSocket, 0) == SOCKET_ERROR) return 1;
    
    		SOCKET iAcceptSocket = pfnAccept(iListenSocket,
    			                   nterpret_cast<SOCKADDR*>(&sSockAddr),
    						 &iLength);
    
    		if(iAcceptSocket == INVALID_SOCKET) return 1;
    
    		pfnCloseSocket(iAcceptSocket);
    
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	pfnCloseSocket(iListenSocket);
    
    	FreeLibrary(hWinSock);
    
    	return 0;
    }
    

    Alles klappt wunderbar nur der bind Funktionsaufruf schlägt fehl mit dem Errorcode WSAENOTSOCK... Irgendjemand eine Idee? Wenn ich die Portangabe weglasse klappt der bind Aufruf. Hab absolut keine Idee an was das liegen könnte.
    Tut mir leid wegen der grottigen Formatierung, kriegs einfach net besser hin.



  • Hab nun herausgefunden wieso es nicht gefunzt hat, falls es interessiert...

    Es lag an der Aufrufkonvention der Funktionen. Ein einfaches _stdcall bei den Funktionspointern und es funktioniert so wie es soll.

    kleines bsp.

    typedef int (*PFNBIND)(SOCKET, const sockaddr*, int);

    ->

    typedef int (_stdcall *PFNBIND)(SOCKET, const sockaddr*, int);



  • Mir ist etwas unklar warum die winsock funktionen überhaupt manuell lädst?



  • Ich schätze er halt sich an die Regel: Warum einfach, wenns auch kompliziert geht



  • Ich habe zur Zeit die Zwangsneurose alle Anwendungen so klein wie möglich zu schreiben 😃 . Klein ist natürlich bezogen auf die reine Anwendungsgröße, und wenn ich so eine Stanadardexe normal Multithreaded(nicht Multithreaded-DLL) erstelle wird die exe schon ohne das ich etwas in das Programm packe 40kb GROß(im Release-Build selbstverständlich). Das ärgert mich einfach... also arbeite ich micht RTDL und spare mir so ein paar kb. Außerdem kann ich falls die erforderliche DLL nicht vorhanden ist alternative Problemlösungen in betracht ziehen, anstatt dass das gesamte Programm den Dienst verweigert.


Anmelden zum Antworten