TCP/IP Server Side App in C++


server.cpp

#include "ws2tcpip.h"
#include "winsock2.h"
#include "windows.h"
#include "MyUtil.h"
#include "Receiver.h"

#define WM_SOCKET WM_APP

SOCKET InitializeWinsock(LPSTR lpszPort);
int GetSocketIndex(SOCKET soc, SOCKET socServer[], int nMaxSocketCount);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd)
{
	MyWindow window(hInst, (LPSTR)"ServerSocket", WindowProc);
	int err = window.create();
	if( err != 0 ){
		return err;
	}
	HWND hWnd = window.getWnd();
	ShowWindow(hWnd, SW_HIDE);

	MSG msg = {0};
	while (1) {
		if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE)) {
			if (!GetMessage (&msg,NULL,0,0)){
				return msg.wParam ;
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		} else {
			/*  */
		}
	}

	return 0;
}


LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static int    nMaxSocketCount = 10;
	static SOCKET socListen = INVALID_SOCKET;
	static SOCKET socServer[10];

	switch (uMsg) {
		case WM_CREATE: {

			socListen = InitializeWinsock((LPSTR)"5000");
			if (socListen == INVALID_SOCKET){
				return -1;
			}
			for (int i = 0; i < nMaxSocketCount; i++){
				socServer[i] = INVALID_SOCKET;
			}
			WSAAsyncSelect(socListen, hwnd, WM_SOCKET, FD_ACCEPT);

			return 0;
		}

	case WM_SOCKET:
		switch (WSAGETSELECTEVENT(lParam)) {
			case FD_ACCEPT: {
				char szHostName[256];
				SOCKADDR_STORAGE sockAddr;
				int i = GetSocketIndex(INVALID_SOCKET, socServer, nMaxSocketCount);
				int nAddrLen = sizeof(SOCKADDR_STORAGE);
				socServer[i] = accept(socListen, (LPSOCKADDR)&sockAddr, &nAddrLen);
				WSAAsyncSelect(socServer[i], hwnd, WM_SOCKET, FD_READ | FD_CLOSE);
				getnameinfo((LPSOCKADDR)&sockAddr, nAddrLen, szHostName, sizeof(szHostName), NULL, 0, 0);
				break;
			}

			case FD_READ: {
				TCHAR szData[256];
				int i = GetSocketIndex((SOCKET)wParam, socServer, nMaxSocketCount);
				int nLen = sizeof(szData);
				int nResult = recv(socServer[i], (char *)szData, nLen, 0);

				/* reply */
				Receiver rcvr;
				rcvr.createMsg((unsigned char*)szData, (size_t)nResult);
				nResult = send(socServer[i], (char*)rcvr.getMsg(), (int)rcvr.getMsgLen(), 0);
				break;
			}

			case FD_CLOSE: {
				int i = GetSocketIndex((SOCKET)wParam, socServer, nMaxSocketCount);
				shutdown(socServer[i], SD_BOTH);
				closesocket(socServer[i]);
				socServer[i] = INVALID_SOCKET;
				break;
			}
		}
		return 0;

	case WM_DESTROY:
			for (int i = 0; i < nMaxSocketCount; i++) {
				if (socServer[i] != INVALID_SOCKET) {
					shutdown(socServer[i], SD_BOTH);
					closesocket(socServer[i]);
				}
			}
			if (socListen != INVALID_SOCKET) {
				closesocket(socListen);
				WSACleanup();
			}
			PostQuitMessage(0);
			return 0;
	default:
		break;
	}

	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

SOCKET InitializeWinsock(LPSTR lpszPort)
{
	WSADATA    wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);

	struct sockaddr_in addr;
	SOCKET socListen = socket(AF_INET, SOCK_STREAM, 0);

	addr.sin_family = AF_INET;
	addr.sin_port = htons(12345);
	addr.sin_addr.S_un.S_addr = INADDR_ANY;

	if(bind(socListen, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
		closesocket(socListen);
		WSACleanup();
		return INVALID_SOCKET;
	}

	if(listen(socListen, 1) == SOCKET_ERROR) {
		closesocket(socListen);
		WSACleanup();
		return INVALID_SOCKET;
	}

	return socListen;
}

int GetSocketIndex(SOCKET soc, SOCKET socServer[], int nMaxSocketCount)
{
	int i = 0;
	for (i = 0; i < nMaxSocketCount; i++) {
		if (socServer[i] == soc){
			break;
		}
	}
	return i;
}
Profile
I have technical job experience in enbedded software development and server side infrastructure/application engineering. I'm interested in programming and computer security.
Objective
To write down my technical knowledge in the place where I can access from anywhere. To share my program source code. To train my writing skill.
Link
  • LinkedIn (preparing)

  • Twitter

  • Facebook (preparing)

  • GitHub

  • StackOverFlow (preparing)

Archives