I need help with sockets.

I get an error which is supposed to mean I have an invalid socket handle. I will copy a post I posted on SO without getting an answer.

Edit: I believe it has to do with my HWND. All the SendMessage in Winsock::Initialize fail too.

Here is Main.cpp up to the point where the error happens:

1
2
3
4
5
6
7
8
9
10
11
12
    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
    {
    	if(SUCCEEDED(CoInitialize(NULL)))
    	{
    		{
    			Game game;
    			
    			game.CreateRessources(hInst);
    			
    			game.ShowMainScreen();
    			
    			game.pWinsock->Initialize(game.Getm_hWnd());


gmae.Getm_hWnd return the private HWND m_hWnd.

Here is Game::CreateRessources(HINSTANCE):

1
2
3
4
5
6
7
8
9
void Game::CreateRessources(HINSTANCE hInst)
    {	
    	m_hWnd=CreateWindowClass(hInst);
    	
    	pMessageLog=CreateMessageLog();
    	pD2DResources=CreateD2DResources(m_hWnd);
    	pWinsock=CreateWinsock();
    	
    }


There is CreateWinsock():

1
2
3
4
5
6
Winsock* CreateWinsock()
    {
    	Winsock* pWinsock=new Winsock;
    
    	return pWinsock;
    }


Winsock::Winsock:

Winsock::Winsock() : Socket(NULL) { }

And finally, Winsock::Initialize(HWND):

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
void Winsock::Initialize(HWND hwnd)
    {
    	WSADATA wsaDat;
    
    	SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Initializing winsock... ");
    
    	int nResult = WSAStartup(MAKEWORD(2,2),&wsaDat);
    	if(nResult!=0)
    	{
    		MessageBox(NULL,"Winsock initialization failed","Critical error",MB_ICONERROR);
    		SendMessage(hwnd,WM_DESTROY,NULL,NULL);
    	}
    
    	SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nCreating a socket... ");
    
    	Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    	if(Socket==INVALID_SOCKET)
    	{
    		MessageBox(NULL,"Socket Creation failed","Critical error",MB_ICONERROR);
    		SendMessage(hwnd,WM_DESTROY,NULL,NULL);
    	}
    
    	SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nRequesting Windows message-based notification of network events... ");
    
    	nResult=WSAAsyncSelect(Socket,hwnd,WM_SOCKET,(FD_CLOSE|FD_READ));
    	if(nResult)
    	{
    		MessageBox(NULL,"WSAAsyncSelect failed","Critical error",MB_ICONERROR);
    		SendMessage(hwnd,WM_DESTROY,NULL,NULL);
    	}
    
    	/* More code */
    }


The line MessageBox(NULL,"WSAAsyncSelect failed","Critical error",MB_ICONERROR); actually executes. WSAGetLastError returns WSAENOTSOCK at this time, which means the following:

"Socket operation on nonsocket.
An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid."

Why does it fails? Does it have to do with my HWND? If you need more pieces of code, ask me.

Edit: My first guess is that I should pass a pointer to the HWND in the game object, like this: void Winsock::Initialize(HWND* phwnd). If it is the case, how can I do that when the Winsock2 functions do not take a pointer as an argument?


Do you there at cpp know what is wrong?
I'm pretty sure I nailed it! I didn't include the winsock2.h header into my winsocket.h header where SOCKET Socket is declared. I am trying to include the header now. I just get that damn list or dozens of errors you sometimes have when including the winsock2.h header.
It doesn't work.
A lot of that doesn't make much sense. Can you post the full content of that header file, the actual errors and the source file that generates the errors?
Actually, I found out there are much more things going wrong in my code.
My code used to work but I changed many things since it was ugly. Moreover, my Game object has to have pointers to multiple other objects since I must have access to these objects when Game is "passed" to WinProc like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	//assert(lParam!=(LPARAM)nullptr);
    	if(msg==WM_CREATE)
    	{
    		LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
    			Game* pGame = (Game*)pcs->lpCreateParams;
    			
    			::SetWindowLongPtrW(
    				hWnd,
    				GWLP_USERDATA,
    				PtrToUlong(pGame)
    				);
    	}
    	else
    	{
    		Game* pGame = reinterpret_cast<Game*>(static_cast<LONG_PTR>(
    			::GetWindowLongPtrW(
    				hWnd,
    				GWLP_USERDATA
    				)));
    
    		switch(msg)
    		{


Since some modification that made my code better structured and made my Game object have pointers to different objects, almost nothing works as it did. So, my code starts like this:

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
    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
    {
    	if(SUCCEEDED(CoInitialize(NULL)))
    	{
    		{
    			Game game;
    			
    			game.CreateRessources(hInst);
    			
    			game.ShowMainScreen();
    
    			game.pWinsock->Initialize(hwnd);
    			
    			ShowWindow(game.Getm_hWnd(),SW_MAXIMIZE);
    			UpdateWindow(game.Getm_hWnd());
    
    			MSG msg;
    			ZeroMemory(&msg,sizeof(MSG));
    
    			while(GetMessage(&msg,NULL,0,0))
    			{
    				TranslateMessage(&msg);
    				DispatchMessage(&msg);
    			}
    		}
    		CoUninitialize();
    	}
    
    	return 0;
    }


There is the Game class:

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
    class Game{
    public:
    	Game();
    	~Game();
    
    	void CreateWindowClass(HINSTANCE);
    	void CreateRessources(HINSTANCE);
    
    	void ShowLoginScreen();
    
    	Winsock* CreateWinsock();
    
    	D2DResources* CreateD2DResources(HWND*);
    
    	HWND Getm_hWnd();
    
    public:
    	D2DResources* pD2DResources;
    	Winsock* pWinsock;
    	MessageLog* pMessageLog;
    
    private:
    	HWND m_hWnd;
    	WNDCLASSEX wClass;
    
    };


Some of its functions:

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
    Game::Game() :
    	pD2DResources(NULL),
    	pWinsock(NULL),
    	pMessageLog(NULL)
    {
    }
    
    void Game::CreateRessources(HINSTANCE hInst)
    {	
    	CreateWindowClass(hInst);
    	
    	pMessageLog=CreateMessageLog();
    
    	HWND* pHWND=&m_hWnd;
    	pD2DResources=CreateD2DResources(pHWND);
    
    	pWinsock=CreateWinsock();
    	
    }
    
    void Game::CreateWindowClass(HINSTANCE hInst)
    {
    	// Create a window class
    	ZeroMemory(&wClass,sizeof(WNDCLASSEX));
    	wClass.cbClsExtra=NULL;
    	wClass.cbSize=sizeof(WNDCLASSEX);
    	wClass.cbWndExtra=NULL;
    	wClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
    	wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    	wClass.hIcon=NULL;
    	wClass.hIconSm=NULL;
    	wClass.hInstance=hInst;
    	wClass.lpfnWndProc=WinProc;
    	wClass.lpszClassName="Window Class";
    	wClass.lpszMenuName=NULL;
    	wClass.style=CS_HREDRAW|CS_VREDRAW;
    
    	if(!RegisterClassEx(&wClass))
    	{
    		int nResult=GetLastError();
    
    		MessageBox(NULL,"Failed to register window class","Window Class Failed",MB_ICONERROR);
    	}
    
    	m_hWnd=CreateWindowEx(NULL,
    			"Window Class",
    			"Game", // Replace with gameName
    			WS_OVERLAPPEDWINDOW,
    			CW_USEDEFAULT,
    			CW_USEDEFAULT,
    			CW_USEDEFAULT,
    			CW_USEDEFAULT,
    			NULL,
    			NULL,
    			hInst,
    			this);
    
    	if(!m_hWnd)
    	{
    		int nResult=GetLastError();
    
    		MessageBox(NULL,"Window class creation failed","Window Class Failed",MB_ICONERROR);
    	}
    }
    Winsock* Game::CreateWinsock()
    {
    	pWinsock = new Winsock;
    
    	return pWinsock;
    }
    
    D2DResources* Game::CreateD2DResources(HWND* pHWND)
    {
    	pD2DResources = new D2DResources;
    
    	pD2DResources->Initialize(pHWND);
    
    	return pD2DResources;
    }

For some reason, the following function is almost the only one that does what it should:

    void Game::ShowMainScreen()
    {
    	HRESULT hr = S_OK;
    
    	ID2D1Bitmap* pBitmap = pD2DResources->GetpCurrentScreen();
    
    	hr = pD2DResources->LoadBitmapFromFile(
    		pD2DResources->GetpRT(),
    		pD2DResources->GetpIWICIF(),
    		L".\\Images\\Maincreen.jpg",
    		0,
    		0,
    		&pBitmap
    		);
    
    
    	if(SUCCEEDED(hr))pD2DResources->SetCurrentScreen(pBitmap);
    	else
    	{
    		_com_error err(hr);
    		LPCTSTR errMsg = err.ErrorMessage();
    		MessageBox(NULL,errMsg,"Error",NULL);
    	}
    }


My WinSocket.h header:

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
 #pragma once

#ifndef WINSOCKET_H
#define WINSOCKET_H

#ifndef WM_SOCKET
#define WM_SOCKET	104
#endif

#ifndef LOG_ADD
#define LOG_ADD		105
#endif

#define WIN32_LEAN_AND_MEAN

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

class Winsock{
public:
	Winsock();

	void Initialize(HWND);

	void ReceiveMsg();

private:
	SOCKET Socket;
	static const char* server;
	static const int port;

	HWND* pHWND;
};

#endif 


Its cpp file:

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
#include "WinSocket.h"

#ifndef WM_SOCKET
#define WM_SOCKET	104
#endif

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

const char* Winsock::server="localhost";
const int Winsock::port=5555;

Winsock::Winsock() :
	Socket(NULL)
{
}

void Winsock::Initialize(HWND hwnd)
{
	WSADATA wsaDat;

	//pHWND = &hwnd;

	SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Initializing winsock... ");

	/*int nResult = WSAStartup(MAKEWORD(2,2),&wsaDat);
	if(nResult!=0)
	{
		MessageBox(NULL,"Winsock initialization failed","Critical error",MB_ICONERROR);
		SendMessage(hwnd,WM_DESTROY,NULL,NULL);
	}*/

	SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nCreating a socket... ");

	/*Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(Socket==INVALID_SOCKET)
	{
		MessageBox(NULL,"Socket Creation failed","Critical error",MB_ICONERROR);
		SendMessage(hwnd,WM_DESTROY,NULL,NULL);
	}*/

	SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nRequesting Windows message-based notification of network events... ");

	/*nResult=WSAAsyncSelect(Socket,hwnd,WM_SOCKET,(FD_CLOSE|FD_READ));
	if(nResult)
	{
		if(WSAGetLastError()==WSAENOTSOCK)MessageBox(hwnd,"WSAENOTSOCK Error!","Error",NULL);
		MessageBox(NULL,"WSAAsyncSelect failed","Critical error",MB_ICONERROR);
		SendMessage(hwnd,WM_DESTROY,NULL,NULL);
	}*/

	SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nResolving host name... ");

	/*struct hostent* host;
	if((host=gethostbyname(server))==NULL)
	{
		MessageBox(NULL,"Unable to resolve host name","Critical error",MB_ICONERROR);
		SendMessage(hwnd,WM_DESTROY,NULL,NULL);
	}*/

	SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nConnecting to server... ");

	/*SOCKADDR_IN SockAddr;
	SockAddr.sin_port=htons(port);
	SockAddr.sin_family=AF_INET;
	SockAddr.sin_addr.s_addr=*((unsigned long*)host->h_addr);

	connect(Socket,(LPSOCKADDR)(&SockAddr),sizeof(SockAddr));*/
}

void Winsock::ReceiveMsg()
{
}


(More in the next reply)
And finally, my WinProc:

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
    LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	if(msg==WM_CREATE)
    	{
    		LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
    			Game* pGame = (Game*)pcs->lpCreateParams;
    			
    			::SetWindowLongPtrW(
    				hWnd,
    				GWLP_USERDATA,
    				PtrToUlong(pGame)
    				);
    	}
    	else
    	{
    		Game* pGame = reinterpret_cast<Game*>(static_cast<LONG_PTR>(
    			::GetWindowLongPtrW(
    				hWnd,
    				GWLP_USERDATA
    				)));
    
    		switch(msg)
    		{
    
    		case WM_PAINT:
    			{
    				pGame->pD2DResources->OnRender(pGame->pMessageLog);
    				ValidateRect(hWnd, NULL);
    			}
    			break;
    
    		case WM_SIZE:
    			{
    				UINT width = LOWORD(lParam);
    				UINT height = HIWORD(lParam);
    				pGame->pD2DResources->OnResize(width, height);
    			}
    			break;
    
    		case WM_DISPLAYCHANGE:
    			{
    				InvalidateRect(hWnd, NULL, FALSE);
    			}
    			break;
    
    		case WM_DESTROY:
    			{
    				//SafeRelease(p2D2Factory);
    				PostQuitMessage(0);
    				return 0;
    			}
    			break;
    
    		case WM_SOCKET:
    			{
    				if(WSAGETSELECTERROR(lParam))
    				{
    					MessageBox(NULL,"Connection to server failed","Connection to server failed",MB_OK|MB_ICONERROR);
    					SendMessage(hWnd,WM_DESTROY,NULL,NULL);
    				}
    
    				switch(WSAGETSELECTEVENT(lParam))
    				{
    				case FD_READ:
    					{
    						pGame->pWinsock->ReceiveMsg();
    					}
    					break;
    
    				case FD_CLOSE:
    					{
    						MessageBox(NULL,"Server closed connection","Server error",MB_ICONINFORMATION|MB_OK);
    						SendMessage(hWnd,WM_DESTROY,NULL,NULL);
    					}
    					break;
    				}
    			}
    			break;
    
    		case LOG_ADD:
    			{
    				pGame->pMessageLog->PutToLog((WCHAR*)lParam);
    				pGame->pD2DResources->OnRender(pGame->pMessageLog);
    			}
    			break;
    		}
    	}
    	return DefWindowProc(hWnd,msg,wParam,lParam);
    }

If I remove the comments in Winsock::Initialize, if(WSAGetLastError()==WSAENOTSOCK) returns true, and this line executes: SendMessage(hwnd,WM_DESTROY,NULL,NULL);

There has to be other things wrong since pGame->pD2DResources->OnRender doesn't print any text like it did and pGame->pD2DResources->OnResize doesn't resize the window anymore.

I've searched for the whole day plus yesterday what is the problem and still haven't found a solution. Please help.


I am trying to get help from StackOverflow at the same time so I just pasted what I posted there and added the header and cpp as you asked.

I'm sorry for posting as much code. I just absolutelly don't know where the error is or are.
Last edited on
debug, debug and again: debug. That's how things work in c/cpp ;]
How to start the debug with visual studio 2010 when the program doesn't break?
Ok, I've taken another look at this. As I keep saying, do not use the Winsock async interface. It's propriety, it introduces a new class of error, it's not worth learning (because it's not portable).

I always recommend using running the socket code in a seperate thread and communicating using standard inter-thread mechanisms/PostThreadMessage.

I have an example somewhere that I wrote for someone last week. It's too large to post, but if you contact me, I can email it to you or stick it on github or something.
InDustWeTrust the best way is actually simplest way.

Take your full program and break the code down into chunks and check to make sure parts of it are working. So check 1 cpp at a time breaking it apart and running a small part of it in its own project in visual studios. If it works then you know that it wasn't the problem and move on. eventually you will find the problem. :)
Topic archived. No new replies allowed.