Winsock2 wrapper - Getting a first exception when using a SOCKET defined in the class header

I cannot for the life of me see where i'm going wrong.
I've got a winsock class, the SOCKET is defined in the Header, but when I try to use it in a function I get a first exception crash. It's ground me to a halt (btw, for anyone who saw the other thread, I solved my win32 wrapper problem).

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    
//Header://
    #ifndef _WINSOCKCLASS_H_
    #define _WINSOCKCLASS_H_
    #define _WINSOCKAPI_
    #include <WinSock2.h>
    #include <String>
    #include <Windows.h>
    class winSockClass
    {
    public:
    winSockClass();
    ~winSockClass();
    bool AsyncSelect( HWND lHwnd );
    bool Startup();
    bool wsConnect(std::string URL, int lPort);
    bool SendMsg(std::string message, LPARAM lParam);
    bool Shutdown();
    std::string lServer;
    int lPort;
    private:
    SOCKET lSocket;
    SOCKADDR_IN sockAddr;
    WSADATA wsaDat;
    struct hostent *host;
    };
    #endif _WINSOCKCLASS_H_


    // CPP: //


    #define _WINSOCKAPI_
    #include "winSockClass.h"
    #include <WinSock2.h>
    #include <vector>

    #pragma comment(lib, "ws2_32.lib")

    winSockClass::winSockClass()
    {
    lSocket = NULL;
    }

    winSockClass::~winSockClass() {}

    bool winSockClass::Startup()
    {
    WSADATA wsaa;
    int nResult = WSAStartup(MAKEWORD(2,2), &wsaa);
    if(nResult != 0)
    {
    return false;
    }

    if (LOBYTE(wsaa.wVersion) != 2 || HIBYTE(wsaa.wVersion) != 2) 
    {
	WSACleanup();
	return false;
    }

    lSocket = socket( AF_INET, SOCK_STREAM, 0 ); // <<--- crash here.
    if( lSocket == INVALID_SOCKET )
    {
    return false;
    }

    return true;
    }


Can anyone help?
Where are you calling the function?
Are you remembering to set "_WIN32_WINNT" to the right version before including your custom header?

You'll want to rethink the "Startup()" member function, you should only ever call "WSAStartup()" once per instance of the application running, that is unless you meant to make "lSocket" static so that it would be shared between instances of the class or something.

... the SOCKET is defined in the Header...
??? By header do you mean winsock2.h? Because we kind of know that already... It just confuses me why you wrote this.

If you don't mind I'd like to copy\paste and run your code. What ever might be wrong isn't obvious unless, like Athar hinted at, it's in your implementation.
Last edited on
I just tried to add the 'win32_winnt' line and the program gave me this: e:\program files\microsoft sdks\windows\v7.0a\include\sdkddkver.h(221): fatal error C1017: invalid integer constant expression

Anyway, full code for the entire program (which doesn't do a lot atm) below:


Main.cpp
1
2
3
4
5
6
7
8
9
10
11
#define _WINSOCKAPI_ 
#include "winClude.h"

int WINAPI WinMain( HINSTANCE hInstance,
					  HINSTANCE hPrevInstance, 
					  LPSTR lpCmdLine,
					  int nCmdShow )
{
	winClude win;
	win.winStart(hInstance, nCmdShow);
}



winClude.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef _WINCLUDE_H_
#define _WINCLUDE_H_
#define _WINSOCKAPI_ 
#include <stdint.h>
#include <Windows.h>
#include "winSockClass.h"

class winClude
{
public:

	int32_t winStart (HINSTANCE hInstance, int32_t nShowCmd);
	static LRESULT CALLBACK StaticWinProc(HWND hwnd, 
										  UINT msg, 
										  WPARAM wParam, 
										  LPARAM lParam);

	winSockClass ws;

protected:
	LRESULT CALLBACK myWinProc(HWND hwnd,
							   UINT msg,
							   WPARAM wParam,
							   LPARAM lParam);

	inline static winClude *GetObjectFromWindow(HWND hwnd)
	{
		return (winClude *)GetWindowLong(hwnd, GWL_USERDATA);
	}
};
#endif 


winClude.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#define _WINSOCKAPI_ 
#include <WinSock2.h>
#include <Windows.h>
#include <string>
#include <stdint.h>
#include "winClude.h"
using namespace std;

int32_t winClude::winStart (HINSTANCE hInstance, int32_t nShowCmd)
{
	WNDCLASSEX wc;
	HWND hwnd;
	MSG msg;

	int32_t screenWidth = 800;
	int32_t screenHeight = 600;

	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = 0;
	wc.lpfnWndProc = winClude::StaticWinProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "myWinClass";
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	if(!RegisterClassEx(&wc))
	{
		return 0;
	}

	int32_t winLeft;
	int32_t winTop;

	winLeft = (GetSystemMetrics(SM_CXSCREEN) / 2) - (screenWidth / 2);
	winTop = (GetSystemMetrics(SM_CYSCREEN) / 2) - (screenHeight / 2);

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
						  "myWinClass",
						  "Window",
						  WS_OVERLAPPEDWINDOW,
						  winLeft, winTop, screenWidth, screenHeight, NULL, NULL, hInstance, NULL);
	
	if(hwnd == NULL)
	{
		return 0;
	}

	ShowWindow(hwnd, nShowCmd);
	UpdateWindow(hwnd);

	while(true)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			// runtime loop code
		}
	}

	return msg.wParam;
}

LRESULT CALLBACK winClude::StaticWinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	winClude *wnd = 0;

	if(msg == WM_NCCREATE)
	{
		wnd = (winClude *)((LPCREATESTRUCT)lParam)->lpCreateParams;
		::SetWindowLong(hwnd, GWL_USERDATA, reinterpret_cast<long>(wnd));
	}
	else
		wnd = reinterpret_cast<winClude *>(::GetWindowLong(hwnd, GWL_USERDATA));
  
	return wnd->myWinProc(hwnd, msg, wParam, lParam);
}

LRESULT CALLBACK winClude::myWinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch ( msg )
	{
		case WM_KEYDOWN:
		{
			switch(wParam)
			{
				case VK_F1:
				{
					ws.Startup();
					ws.AsyncSelect(hwnd);
					ws.wsConnect("216.239.138.52", 80);
					ws.SendMsg("GET /index.php HTML/1.0", lParam);
				}
				case VK_ESCAPE:
				{
					PostQuitMessage( 0 );
				}
			}
		}
		case 104: // WM_SOCKET
		{
			if(WSAGETSELECTERROR(lParam))
				break;

			switch(WSAGETSELECTEVENT(lParam))
			{
				case FD_READ:
				{

				}
				case FD_CLOSE:
				{

				}
			}
		}
		case WM_CLOSE:
		{
			ws.Shutdown();
			DestroyWindow( hwnd );
			break;
		}
		case WM_DESTROY:
		{
			PostQuitMessage( 0 );
			break;
		}
		default:
			return DefWindowProc( hwnd, msg, wParam, lParam );
	}
	return 0;
}


winSockClass.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef _WINSOCKCLASS_H_
#define _WINSOCKCLASS_H_
#define _WINSOCKAPI_ 

#include <WinSock2.h>
#include <String>
#include <Windows.h>

class winSockClass
{
public:
	winSockClass();
	~winSockClass();
	bool AsyncSelect( HWND lHwnd );
	bool Startup();
	bool wsConnect(std::string URL, int lPort);
	bool SendMsg(std::string message, LPARAM lParam);
	bool Shutdown();

	std::string lServer;
	int lPort;
private:
	SOCKET lSocket;
	SOCKADDR_IN sockAddr;
	WSADATA wsaDat;
	struct hostent *host;
};

#endif _WINSOCKCLASS_H_ 


winSockClass.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#define _WINSOCKAPI_ 
#define _WIN32_WINNT
#include "winSockClass.h"
#include <WinSock2.h>
#include <vector>

#pragma comment( lib, "ws2_32.lib" )

winSockClass::winSockClass()
{
	lSocket = NULL;
}

winSockClass::~winSockClass() {}

bool winSockClass::Startup()
{
	WSADATA wsaa;
	int nResult = WSAStartup( MAKEWORD( 2, 2 ), &wsaa );
	if( nResult != 0 )
	{

		return false;
	}

	if ( LOBYTE( wsaa.wVersion ) != 2 || HIBYTE( wsaa.wVersion ) != 2 ) 
	{
		WSACleanup();
		return false;
	}

	lSocket = socket( AF_INET, SOCK_STREAM, 0 );
	if( lSocket == INVALID_SOCKET )
	{
		return false;
	}

	return true;
}

bool winSockClass::wsConnect( std::string URL, int lPort )
{
	if( ( host = ( hostent * )gethostbyname( URL.c_str() ) ) == NULL )
	{
		return false;
	}

	sockAddr.sin_port=htons(lPort);
	sockAddr.sin_family=AF_INET;		
	sockAddr.sin_addr.s_addr=*( ( unsigned long* )host->h_addr );

	connect( lSocket, ( LPSOCKADDR )( &sockAddr ), sizeof( sockAddr ) );

	return true;
}

bool winSockClass::AsyncSelect( HWND lHwnd )
{
	int nResult = WSAAsyncSelect( lSocket, lHwnd, 104, (FD_CLOSE | FD_READ));
	if ( nResult )
	{
		return false;
	}

	return true;
}

bool winSockClass::SendMsg(std::string message, LPARAM lParam)
{
	send( lSocket, message.c_str(), message.size(), 0 );

	if( WSAGETSELECTERROR( lParam ) )
	{
		return false;
	}

	return true;
}

bool winSockClass::Shutdown()
{
	if( lSocket != NULL )
	{
		closesocket( lSocket );
		return true;
	}
	else return false;

	return true;
}



As for the startup function, you're right. It needs redoing, but atm, I just wanna get it working before making it fully functional ya know? :)
I expected something like that - you're calling Startup() for an invalid winSockClass instance, which is caused by calling myWinProc() for an invalid winClude instance. So it crashes on the first attempt to access a member variable.

All of this isn't surprising, considering where you're getting your instance from:
wnd = (winClude *)((LPCREATESTRUCT)lParam)->lpCreateParams;
You passed NULL for the creation parameter when calling CreateWindowEx.

You seriously need to stop this wild casting and use a better solution.
hmm, ok. I'll go back to the drawing board then :)
Thanks :)
Topic archived. No new replies allowed.