要把界面搬进浏览器,缺的是一个能接收请求的进程。7.1.0 没有引入任何 HTTP 库,而是用 Winsock 直接写了一个够用的服务器 —— 它只需要服务一个客户端(本机的浏览器窗口)。
启动与单实例
#define PORT 18889
// 端口已被监听 → 说明后端已在运行,本进程只把窗口拉起来就退出
if (IsPortListening()) { OpenAppWindow(); WSACleanup(); return 0; }
sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // 仅本机可访问
addr.sin_port = htons(PORT);
setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
bind(ls, (sockaddr*)&addr, sizeof(addr));
listen(ls, 8);
while (true) {
SOCKET cs = accept(ls, nullptr, nullptr);
_beginthreadex(nullptr, 0, ClientThread, (void*)(intptr_t)cs, 0, nullptr);
}- 只绑回环地址 —— 外部网络无法访问这个端口,别的机器连不上,也就无从调用本机的文件操作接口
- 单实例 —— 重复双击 exe 不会起第二个服务、不会报端口占用,而是直接把已有的窗口拉到前台
- 一连接一线程 —— 每个请求开一个线程处理,前端并发几个请求不会互相阻塞
路由
请求路径直接映射到功能函数,一共 22 个接口:
| 分类 | 接口 |
|---|---|
| 环境 | ping · info · gppdetect · setgpp · browse · maketsdir |
| 生成 | generate · writefiles · bigfile · rename · genrun · genlib |
| 编译与打包 | compile · zip · savezip |
| 更新 | update · updatedl · updstatus · updlaunch · installed |
| 云端 | cloud(统一转发账号 / 私信 / AI) |
| 工具 | tool |
请求怎么解析
// 读到完整的 body 为止(按 Content-Length 判断,而不是「一次 recv 就当完事」)
while ((n = recv(sock, buf, sizeof(buf), 0)) > 0) {
raw.append(buf, n);
size_t hdrEnd = raw.find("\r\n\r\n");
if (hdrEnd != string::npos) {
string headers = raw.substr(0, hdrEnd);
size_t clPos = headers.find("Content-Length:");
int cl = (clPos != string::npos) ? atoi(headers.c_str() + clPos + 15) : 0;
if (raw.size() - (hdrEnd + 4) >= (size_t)cl) break;
} else if (raw.size() > 64 * 1024) break;
}
// 浏览器的跨域预检必须先应答,否则带 JSON 的 POST 根本发不出来
if (method == "OPTIONS") { SendPreflight(sock); ... return 0; }
// 单个请求出异常不能拖垮整个服务进程
try { content = HandleRequest(req); }
catch (...) { content = "{\"ok\":false,\"error\":\"server_internal\"}"; }打开的是一个应用窗口,不是浏览器标签
后端启动后会拉起浏览器,但用 --app 模式启动,呈现的是没有地址栏与标签页的独立窗口 —— 看起来就是一个桌面程序:
static wstring FindBrowserExe() {
// 1) 注册表 App Paths(Chrome / Edge,含 WOW6432Node)
// 2) 常见安装路径:Chrome 优先(--app 行为更稳定),Edge 兜底
}
wstring args = L"--app=" + url + L" --window-size=1320,880 "
L"--window-position=center --disable-features=Translate";
ShellExecuteW(nullptr, L"open", browser.c_str(), args.c_str(), nullptr, SW_SHOWNORMAL);