// SimpleServer.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <conio.h>
#include "winsock.h"
//#include "afxwin.h"
#pragma comment(lib, "ws2_32.lib")
const int MAXCON = 5;
SOCKET server;
void ErrorHandler(const char *msg);
void StartServerThreadProc(LPVOID param);
void HandleClientThreadProc(LPVOID param);
int _tmain(int argc, _TCHAR* argv[])
{
int PortNum = 9901;
DWORD id;
if (argc == 2)
PortNum = atoi(argv[1]);
HANDLE hServer = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartServerThreadProc,
(LPVOID)&PortNum, 0, &id);
std::cout << "Press ESCAPE to quit ..." << std::endl;
while(getch() != 27);
TerminateThread(hServer, 0);
CloseHandle(hServer);
closesocket(server);
WSACleanup();
std::cout << "Main thread exited." << std::endl;
//getch();
return 0;
}
void StartServerThreadProc(LPVOID param)
{
int PortNum = *(int *)param;
WSAData w;
if (WSAStartup(0x101, &w) != 0)
{
ErrorHandler("WSAStartup Error.");
return;
}
server = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in local;
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = htons(PortNum);
if (INVALID_SOCKET == server)
{
ErrorHandler("Socket initialization Error.");
return;
}
if (bind(server, (struct sockaddr *)&local, sizeof(local)) != 0)
{
ErrorHandler("Socket binding Error.");
return;
}
std::cout << "Socket binding to port #" << PortNum << std::endl;
if (listen(server, MAXCON) != 0)
{
ErrorHandler("Socket listening Error.");
return;
}
std::cout << "Socket listen with max conn = " << MAXCON << std::endl;
SOCKET client;
SOCKADDR_IN client_addr;
//if client_addr_len not initialized, will receive from 204.204.204.204 endlessly
int client_addr_len = sizeof(client_addr);
char buf[512];
DWORD thread_id;
int count = 0;
while(count < 1000)
{
sprintf(buf, "Hello.");
client = accept(server, (struct sockaddr *)&client_addr, &client_addr_len);
std::cout << "Connection #" << count << " from " << inet_ntoa(client_addr.sin_addr) << std::endl;
//send(client, buf, strlen(buf), 0);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HandleClientThreadProc,
(LPVOID)client, 0, &thread_id);
//closesocket(client);
count++;
}
}
void HandleClientThreadProc(LPVOID param)
{
SOCKET client = (SOCKET)param;
SOCKADDR_IN client_addr;
memset(&client_addr, 0, sizeof(client_addr));
int addr_len = sizeof(client_addr);
char buf[512];
strcpy(buf, "Server Ready");
send(client, buf, strlen(buf), 0);
int n;
getsockname(client, (struct sockaddr *)&client_addr, &addr_len);
while (true)
{
n = recv(client, buf, 512, 0);
if (SOCKET_ERROR == n)
break;
buf[n] = 0;
std::cout << "[" << inet_ntoa(client_addr.sin_addr) << "]: "
<< buf << std::endl;
}
std::cout << "[" << inet_ntoa(client_addr.sin_addr) << "]: "
<< " disconnected." << std::endl;
closesocket(client);
}
std::string GetLastErrorMsg()
{
LPVOID lpMsgBuf;
if (!FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL ))
{
// Handle the error.
return "";
}
std::string ret = std::string((char*)lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
return ret;
}
void ErrorHandler(const char *msg)
{
std::cout << msg << std::endl;
std::string s = GetLastErrorMsg();
std::cout << "Last Error: " << s.c_str() << std::endl;
WSACleanup();
getch();
}