自己做的web服务器软件(只有最普通的功能)

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <cstring>
#include <algorithm>
#include <map>
#include <thread>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <sys/stat.h>
#include <direct.h>
#include <locale>
#include <ctime>
#include <stdexcept>
#include <windows.h>
#include <tchar.h>
#include <cstdio>
#include <commctrl.h>

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

using namespace std;

// 全局变量
HWND hWnd, hLogEdit, hStatusStatic, hStartButton, hStopButton, hFontCombo, hSizeCombo;
HANDLE hServerThread = NULL;
bool g_isServerRunning = false;
CRITICAL_SECTION logCriticalSection;
int g_winsockRefCount = 0;

// 字体相关
int g_fontSize = 20;
HFONT g_hFont = NULL;
const int MIN_FONT_SIZE = 12, MAX_FONT_SIZE = 24;
TCHAR g_currentFont[64] = _T("Consolas");

const TCHAR *fontList[] = { _T("微软雅黑"), _T("宋体"), _T("黑体"), _T("楷体"), _T("隶书"), _T("Consolas"), _T("Arial"), _T("SimSun"), _T("SimHei"), _T("KaiTi") };
const int fontCount = sizeof(fontList) / sizeof(fontList[0]);

// 服务器核心类前置声明
class WebServer;

// 日志管理器类
class LogManager {
	private:
		string logDir, sysLogFile, netLogFile;
		HWND hLogWnd;

		void ensureLogDirectory() {
			struct stat info;
			if (stat(logDir.c_str(), &info) != 0) {
				if (_mkdir(logDir.c_str()) != 0)
					throw runtime_error("无法创建日志目录: " + logDir);
			} else if (!(info.st_mode & S_IFDIR))
				throw runtime_error(logDir + " 不是一个目录");
		}

	public:
		LogManager(const string &dir = "log", HWND logWnd = NULL) : logDir(dir), hLogWnd(logWnd),
			sysLogFile(dir + "\\sys.log"), netLogFile(dir + "\\net.log") {
			ensureLogDirectory();
		}

		string getTimestamp() {
			time_t now = time(nullptr);
			tm localTime;
			localtime_s(&localTime, &now);
			char buffer[80];
			strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &localTime);
			return "[" + string(buffer) + "] ";
		}

		void writeSystemLog(const string &message) {
			string logEntry = getTimestamp() + message;
			ofstream(logEntry, ios::app) << logEntry << endl;
			addToLog("系统: " + logEntry);
		}

		void writeNetworkLog(const string &message) {
			string logEntry = getTimestamp() + message;
			ofstream(netLogFile, ios::app) << logEntry << endl;
			addToLog("网络: " + logEntry);
		}

		void addToLog(const string &message) {
			if (!hLogWnd)
				return;
			EnterCriticalSection(&logCriticalSection);
			int length = GetWindowTextLength(hLogWnd);
			SendMessage(hLogWnd, EM_SETSEL, length, length);
			SendMessage(hLogWnd, EM_REPLACESEL, FALSE, (LPARAM)(message + "\r\n").c_str());
			SendMessage(hLogWnd, WM_VSCROLL, SB_BOTTOM, 0);
			LeaveCriticalSection(&logCriticalSection);
		}
};

// 配置管理器类
class ConfigManager {
	private:
		map<string, string> configs;
		string configFile;

		void parseLine(const string &line) {
			size_t commentPos = line.find('#'), start = line.find_first_not_of(" \t");
			if (start == string::npos)
				return;

			string lineContent = (commentPos != string::npos) ? line.substr(0, commentPos) : line;
			lineContent = lineContent.substr(start, lineContent.find_last_not_of(" \t") - start + 1);

			size_t spacePos = lineContent.find_first_of(" \t");
			if (spacePos == string::npos)
				return;

			string key = lineContent.substr(0, spacePos);
			size_t valueStart = lineContent.find_first_not_of(" \t", spacePos);
			if (valueStart != string::npos)
				configs[key] = lineContent.substr(valueStart);
		}

		void logError(const string &message) {
			cerr << "[错误] " << message << endl;
			EnterCriticalSection(&logCriticalSection);
			int length = GetWindowTextLength(hLogEdit);
			SendMessage(hLogEdit, EM_SETSEL, length, length);
			SendMessage(hLogEdit, EM_REPLACESEL, FALSE, (LPARAM)(("[错误] " + message + "\r\n").c_str()));
			SendMessage(hLogEdit, WM_VSCROLL, SB_BOTTOM, 0);
			LeaveCriticalSection(&logCriticalSection);
		}

		void checkRequiredConfigs() {
			vector<string> required = {"listen", "default"};
			for (const string &key : required)
				if (configs.find(key) == configs.end() || configs[key].empty())
					logError("配置文件缺少必要项: " + key);

			try {
				stoi(configs["listen"]);
			} catch (...) {
				logError("配置项listen必须是有效的端口号");
			}
		}

	public:
		ConfigManager(const string &file = "config.txt") : configFile(file) {
			configs["root"] = "page";
			configs["404page"] = "404.html";
			configs["charset"] = "UTF-8";

			ifstream cfgFile(configFile);
			if (cfgFile.is_open()) {
				string line;
				while (getline(cfgFile, line))
					parseLine(line);
			} else
				logError("未找到配置文件: " + configFile);

			checkRequiredConfigs();
		}

		string getString(const string &key) {
			return configs.count(key) ? configs[key] : "";
		}
		int getInt(const string &key) {
			try {
				return configs.count(key) ? stoi(configs[key]) : 0;
			} catch (...) {
				return 0;
			}
		}
};

// Web服务器类(双栈支持)
class WebServer {
	private:
		int port;
		string rootDir, defaultPage, error404, charset;
		SOCKET ipv4Socket, ipv6Socket;
		LogManager &logger;
		bool isRunning;
		thread ipv4Thread, ipv6Thread;

		string urlDecode(const string &encoded) {
			string decoded;
			for (size_t i = 0; i < encoded.size(); i++) {
				if 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值