Here is the entire program source:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <tchar.h>
#include <stdio.h>
#include <string>
using std::string;
#pragma comment (lib, "Ws2_32.lib")
#pragma warning (disable: 6387)
void GetLastError(int iErrorNum);
void SendResponse(SOCKET client, LPCSTR lpstrResponse);
void SetBlockingMode(SOCKET sock, BOOL blocking);
void WriteToLogFile(LPCSTR lpstrMessage);
int WebServer(LPTSTR lpstrServiceName);
int _tmain(int argc, TCHAR* argv[])
{
TCHAR szServiceName[MAX_PATH];
wmemset(szServiceName, 0x00, _countof(szServiceName));
// Get ServiceName (port)
if (argc == 1) {
_tcscpy_s(szServiceName, _countof(szServiceName), L"9000");
}
else {
_tcscpy_s(szServiceName, _countof(szServiceName), argv[1]);
}
// Start web server
return WebServer(szServiceName);
}
void GetLastError(int iErrorNum)
{
CHAR szBuffer[MAX_PATH];
memset(szBuffer, 0x00, sizeof(szBuffer));
sprintf_s(szBuffer, sizeof(szBuffer), "ErrorNum: %d", iErrorNum);
WriteToLogFile(szBuffer);
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
iErrorNum, LANG_NEUTRAL, szBuffer, MAX_PATH, 0);
WriteToLogFile(szBuffer);
WSASetLastError(0);
}
void SendResponse(SOCKET client, LPCSTR lpstrResponse)
{
int length = 0;
length = strlen(lpstrResponse);
send(client, lpstrResponse, length, 0);
}
void SetBlockingMode(SOCKET sock, BOOL blocking)
{
u_long argp;
if (blocking) {
argp = 0;
}
else {
argp = 1;
}
ioctlsocket(sock, FIONBIO, &argp);
}
void WriteToLogFile(LPCSTR lpstrMessage)
{
HANDLE hFile;
DWORD dwWritten = 0;
hFile = CreateFileA("C:\\Temp\\LogFile.txt",
FILE_APPEND_DATA, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
WriteFile(hFile, lpstrMessage, (DWORD)strlen(lpstrMessage), &dwWritten, 0);
WriteFile(hFile, "\r\n", 2, &dwWritten, 0);
CloseHandle(hFile);
}
}
int WebServer(LPTSTR lpstrServiceName)
{
WSADATA wsaData;
int iResult = 0;
CHAR szRecvBuffer[1024];
string ReceivedData;
SYSTEMTIME lt;
char szMsgText[MAX_PATH];
char szTemp[34];
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfoW* result = NULL;
struct addrinfoW hints;
memset(szMsgText, 0x00, sizeof(szMsgText));
memset(szTemp, 0x00, sizeof(szTemp));
// Start Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
WriteToLogFile("WSAStartup error: ");
GetLastError(iResult);
return 1;
}
// Initialze the structure
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = GetAddrInfoW(NULL, lpstrServiceName, &hints, &result);
if (iResult != 0) {
WriteToLogFile("GetAddrInfoW error: ");
GetLastError(iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
WriteToLogFile("Socket error: ");
GetLastError(WSAGetLastError());
FreeAddrInfoW(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
WriteToLogFile("Bind error: ");
GetLastError(WSAGetLastError());
FreeAddrInfoW(result);
WSACleanup();
return 1;
}
// Cleanup
FreeAddrInfoW(result);
// Listen for connections
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
WriteToLogFile("Listen error: ");
GetLastError(WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Make the socket blocking
SetBlockingMode(ListenSocket, TRUE);
while (0 == 0)
{
// Accept incoming connection
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
WriteToLogFile("Accept error: ");
GetLastError(WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Make the socket non-blocking
SetBlockingMode(ClientSocket, FALSE);
// Receive the data
ReceivedData.clear();
do {
memset(szRecvBuffer, 0x00, sizeof(szRecvBuffer));
iResult = recv(ClientSocket, szRecvBuffer, sizeof(szRecvBuffer) - 1, 0);
if (iResult > 0) {
ReceivedData.append(szRecvBuffer);
}
} while (iResult != SOCKET_ERROR);
// determine the current time
GetLocalTime(<);
// format the time into a localized string
strcpy_s(szMsgText, sizeof(szMsgText), "Current Timestamp: ");
GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, <, NULL, szTemp, sizeof(szTemp));
strcat_s(szMsgText, sizeof(szMsgText), szTemp);
strcat_s(szMsgText, sizeof(szMsgText), " ");
GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER + TIME_FORCE24HOURFORMAT, <, NULL, szTemp, sizeof(szTemp));
strcat_s(szMsgText, sizeof(szMsgText), szTemp);
sprintf_s(szTemp, sizeof(szTemp), ".%03d", lt.wMilliseconds);
strcat_s(szMsgText, sizeof(szMsgText), szTemp);
strcat_s(szMsgText, sizeof(szMsgText), "\r\n");
// Send reply
SendResponse(ClientSocket, "HTTP/1.1 200 OK\r\n");
SendResponse(ClientSocket, "Content-Type: text/plain; charset=UTF-8\r\n");
SendResponse(ClientSocket, "\r\n");
SendResponse(ClientSocket, szMsgText);
if (ReceivedData.length() > 0) {
SendResponse(ClientSocket, "\r\n");
SendResponse(ClientSocket, "ReceivedData:\r\n");
SendResponse(ClientSocket, "\r\n");
SendResponse(ClientSocket, ReceivedData.c_str());
}
// Shutdown client socket
iResult = shutdown(ClientSocket, SD_SEND);
// Close client socket
closesocket(ClientSocket);
}
// Close listen socket
closesocket(ListenSocket);
// Cleanly shut down Winsock
WSACleanup();
return 0;
}