Thread: win32 Winsock problem

  1. #1
    Climber spoon_'s Avatar
    Join Date
    Jun 2002
    Location
    ATL
    Posts
    182

    win32 Winsock problem

    I'm trying to incorporate winsock into a win32 program. The program doubles as a server/client. If you click the button 'Listen', you are tagged as a server. If you click the button 'Connect', you are tagged as a client.

    Both of these programs use the loopback address, i.e. 127.0.0.1, for testing.

    The only problem is when you run the server and click, 'Listen', and then run the program and click 'Connect', it never reaches FD_ACCEPT (WSAAsyncSelect). I've tried many things, maybe someone here can pinpoint the error I've made.

    Be sure to link wsock32.lib when compiling.
    (I am using msvc++6 pro and xp pro).

    heres the code...
    Code:
    #include<windows.h>
    #include<winsock.h>
    #include<string.h>
    
    #define SOCK_DATA_ARRIVAL (WM_USER + 1)
    
    
    #define BUTTON_LISTEN 1
    #define BUTTON_CONNECT 2
    #define BUTTON_CLOSE 3
    #define BUTTON_SEND 4
    
    #define EDIT_LISTEN 5
    #define EDIT_SEND 6
    
    int Port = 5553;
    SOCKET sock_listen, sock_s;
    SOCKADDR_IN my_addr, remote_addr;
    WSADATA wsData;
    
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    HINSTANCE hInst;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int ShowCmd)
    {
    	TCHAR appname[] = "App";
    	MSG msg;
    	HWND hwnd;
    	WNDCLASS wclass;
    
    	wclass.style = CS_HREDRAW | CS_VREDRAW;
    	wclass.lpfnWndProc = WndProc;
    	wclass.cbClsExtra = 0;
    	wclass.cbWndExtra = 0;
    	wclass.hInstance = hInstance;
    	wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    	wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
    	wclass.lpszMenuName = NULL;
    	wclass.lpszClassName = appname;
    
    	if(!(RegisterClass(&wclass)))
    	{
    		MessageBox(NULL, "RegisterClass(*WNDCLASS) Failed.", "Error", NULL);
    		return 0;
    	}
    
    	hInst = hInstance;
    
    	hwnd = CreateWindowEx(
    		NULL,
    		appname,
    		"Window Title",
    		WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,
    		0,
    		0,
    		275,
    		255,
    		NULL,
    		NULL,
    		hInstance,
    		NULL);
    
    	ShowWindow(hwnd, ShowCmd);
    	UpdateWindow(hwnd);
    
    	WSAAsyncSelect(sock_listen, hwnd, SOCK_DATA_ARRIVAL, FD_ACCEPT|FD_READ|FD_CONNECT);
    	WSAAsyncSelect(sock_s, hwnd, SOCK_DATA_ARRIVAL, FD_ACCEPT|FD_READ|FD_CONNECT);
    
    	while(GetMessage(&msg, 0, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	WSACleanup();
    
    	return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static int xClient, yClient,
    		cxChar, cxCaps, cyChar;
    
    	static bool isserver;
    
    	HDC hdc;
    	PAINTSTRUCT ps;
    	TEXTMETRIC tm;
    
    	switch(message)
    	{
    	case WM_CREATE:
    		{
    			hdc = GetDC(hwnd);
    			GetTextMetrics(hdc, &tm);
    			cxChar = tm.tmAveCharWidth;
    			cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
    			cyChar = tm.tmHeight + tm.tmExternalLeading;
    
    
    			CreateWindowEx(
    				NULL,
    				"BUTTON",
    				"Listen",
    				WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    				10,
    				10,
    				75,
    				30,
    				hwnd,
    				(HMENU) BUTTON_LISTEN,
    				hInst,
    				NULL);
    
    			CreateWindowEx(
    				NULL,
    				"BUTTON",
    				"Connect",
    				WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    				95,
    				10,
    				75,
    				30,
    				hwnd,
    				(HMENU) BUTTON_CONNECT,
    				hInst,
    				NULL);
    
    			CreateWindowEx(
    				NULL,
    				"BUTTON",
    				"Close",
    				WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    				180,
    				10,
    				75,
    				30,
    				hwnd,
    				(HMENU) BUTTON_CLOSE,
    				hInst,
    				NULL);
    
    			CreateWindowEx(
    				NULL,
    				"EDIT",
    				"Listen Text",
    				WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | ES_MULTILINE,
    				10,
    				50,
    				245,
    				100,
    				hwnd,
    				(HMENU) EDIT_LISTEN,
    				hInst,
    				NULL);
    
    			CreateWindowEx(
    				NULL,
    				"EDIT",
    				"Send Text",
    				WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_AUTOHSCROLL,
    				10,
    				160,
    				245,
    				20,
    				hwnd,
    				(HMENU) EDIT_SEND,
    				hInst,
    				NULL);
    
    			CreateWindowEx(
    				NULL,
    				"BUTTON",
    				"Send",
    				WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    				180,
    				190,
    				75,
    				30,
    				hwnd,
    				(HMENU) BUTTON_SEND,
    				hInst,
    				NULL);
    
    			return 0;
    		}
    	case WM_COMMAND:
    		{
    			switch(HIWORD(wParam))
    			{
    			case BN_CLICKED:
    				{
    					switch(LOWORD(wParam))
    					{
    					case BUTTON_LISTEN:
    						{
    							WSAStartup(MAKEWORD(1,1), &wsData);
    
    							isserver = true;
    
    							sock_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    							if(sock_listen == SOCKET_ERROR)
    							{
    								MessageBox(hwnd, "socket() failed.", "server", MB_OK);
    								return 0;
    							}
    
    							my_addr.sin_family = AF_INET;
    							my_addr.sin_port = htons(Port);
    							my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    							if((bind(sock_listen, (struct sockaddr *) &my_addr, sizeof(my_addr))) == SOCKET_ERROR)
    							{
    								MessageBox(hwnd, "bind() failed.", "server", MB_OK);
    								return 0;
    							}
    
    							if((listen(sock_listen, 10)) == SOCKET_ERROR)
    							{
    								MessageBox(hwnd, "listen() failed.", "server", MB_OK);
    								return 0;
    							}
    
    							MessageBox(hwnd, "listening for connections.", "server", MB_OK);
    
    							return 0;
    						}
    					case BUTTON_CONNECT:
    						{
    							WSAStartup(MAKEWORD(1,1), &wsData);
    
    							isserver = false;
    							char szAddress[64] = "127.0.0.1";
    							char iAddressLen = strlen(szAddress);
    
    							sock_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    							if(sock_s == SOCKET_ERROR)
    							{
    								MessageBox(hwnd, "socket() failed.", "client", MB_OK);
    								return 0;
    							}
    
    							remote_addr.sin_family = AF_INET;
    							remote_addr.sin_port = htons(Port);
    							remote_addr.sin_addr.s_addr = inet_addr(szAddress);
    
    							if((connect(sock_s, (struct sockaddr *) &remote_addr, sizeof(remote_addr))) == SOCKET_ERROR)
    							{
    								MessageBox(hwnd, "connect() failed.", "client", MB_OK);
    								return 0;
    							}
    
    							MessageBox(hwnd, "connect?", "", NULL);
    
    							return 0;
    						}
    					case BUTTON_CLOSE:
    						{
    							closesocket(sock_s);
    							closesocket(sock_listen);
    							WSACleanup();
    							return 0;
    						}
    					case BUTTON_SEND:
    						{
    							char szSendBuffer[512];
    
    							GetDlgItemText(hwnd, EDIT_SEND, szSendBuffer, 512);
    
    							if((send(sock_s, szSendBuffer, strlen(szSendBuffer), 0)) == SOCKET_ERROR)
    							{
    								MessageBox(hwnd, "send() failed.", (isserver == true) ? "server" : "client", MB_OK);
    								return 0;
    							}
    
    							send(sock_s, szSendBuffer, strlen(szSendBuffer), 0);
    
    							return 0;
    						}
    					}
    				}
    			}
    			return 0;
    		}
    	case SOCK_DATA_ARRIVAL:
    		{
    			switch(LOWORD(lParam))
    			{
    			case FD_READ:
    				{
    					int ret;
    					char szBuffer[512];
    					
    					ret = recv(sock_s, szBuffer, sizeof(szBuffer), 0);
    
    					if(ret == SOCKET_ERROR)
    					{
    						MessageBox(hwnd, "recv() failed.", (isserver == true) ? "server" : "client", MB_OK);
    						return 0;
    					}
    
    					szBuffer[ret] = '\0';
    
    					SetDlgItemText(hwnd, EDIT_LISTEN, szBuffer);
    
    					return 0;
    				}
    			case FD_ACCEPT:
    				{
    					int len;
    					len = sizeof(remote_addr);
    					sock_s = accept(sock_listen, (struct sockaddr *) &remote_addr, &len);
    
    					MessageBox(hwnd, "connection received.", "server", NULL);
    					return 0;
    				}
    			case FD_CONNECT:
    				{
    					MessageBox(hwnd, "socket connected.", (isserver == true) ? "server" : "client", NULL);
    					return 0;
    				}
    			}
    		}
    	case WM_PAINT:
    		{
    			hdc = BeginPaint(hwnd, &ps);
    			EndPaint(hwnd, &ps);
    			return 0;
    		}
    	case WM_SIZE:
    		{
    			xClient = LOWORD(lParam);
    			yClient = HIWORD(lParam);
    			return 0;
    		}
    	case WM_DESTROY:
    		{
    			PostQuitMessage(0);
    			return 0;
    		}
    	}
    
    	return DefWindowProc(hwnd, message, wParam, lParam);
    }
    thank you,
    spoon_
    {RTFM, KISS}

  2. #2
    Registered User johnnie2's Avatar
    Join Date
    Aug 2001
    Posts
    186
    If you were to check the return value of the two WSAAsyncSelect() calls after you created the main window, you'd most likely find that they've returned the error WSANOTINITIALISED. Since a WSAStartup() call is not made before calling WSAAsyncSelect(), none of the sockets will be registered as asynchronous. Place your WSAStartup() call before any other socket functions and see what happens.
    "Optimal decisions, once made, do not need to be changed." - Robert Sedgewick, Algorithms in C

  3. #3
    Climber spoon_'s Avatar
    Join Date
    Jun 2002
    Location
    ATL
    Posts
    182
    yep, that was the problem. thanks.

    i have another question.....

    Code:
    case FD_READ:
    {
    	char szRead[1024];
    	int ReadLen = recv(sock_s, szRead, sizeof(szRead), 0);
    
    	szRead[ReadLen] = '\0';
    					
    	SetDlgItemText(hwnd, EDIT_LISTEN, szRead);
    
    	break;
    }
    how do I make a newline in the Edit Control?

    when i set szRead[ret] = '\n', it doesnt work, nor '\r' nor '\f'.

    So far it will just overwrite what ever is on the first line.

    thanks
    Last edited by spoon_; 07-18-2002 at 03:52 PM.
    {RTFM, KISS}

  4. #4
    Registered User
    Join Date
    Jul 2002
    Posts
    36
    I think newline in Edit Controls was "\r\n"
    "I don't know with what weapons World War III will be fought... but World War IV will be fought with sticks and stones." - Albert Einstein

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Win32 Console - Simple graphical problem
    By INFERNO2K in forum C++ Programming
    Replies: 0
    Last Post: 12-09-2005, 09:34 AM
  2. Win32 C++ app problem
    By kwm32 in forum Windows Programming
    Replies: 4
    Last Post: 03-19-2004, 03:38 AM
  3. OpenSSL and Win32 SSL API :: SSL/TLS
    By kuphryn in forum Networking/Device Communication
    Replies: 0
    Last Post: 03-10-2004, 07:46 PM
  4. WinSock Problem
    By loobian in forum C++ Programming
    Replies: 1
    Last Post: 02-09-2002, 11:25 AM
  5. Small Winsock problem...
    By SyntaxBubble in forum C++ Programming
    Replies: 0
    Last Post: 02-09-2002, 10:09 AM