使用 QtWebApp 编写 Web 服务器应用程序 (stefanfrings.de)
HTTP请求协议格式如下:
请求行:[请求方法] + [URI] + [HTTP版本]。
请求报头:请求的属性,这些属性都是以key: value的形式按行陈列的。Content-Length
空行:遇到空行表示请求报头结束。
请求正文:请求正文允许为空字符串,如果请求正文存在,则在请求报头中会有一个Content-Length属性来标识请求正文的长度。
HTTP响应协议格式如下:
状态行:[HTTP版本] + [状态码] + [状态码描述]。
响应报头:响应的属性,这些属性都是以key: value的形式按行陈列的。
空行:遇到空行表示响应报头结束。
响应正文:响应正文允许为空字符串,如果响应正文存在,则在响应报头中会有一个Content-Length属性来标识响应正文的长度。
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>
#pragma comment(lib, "ws2_32.lib")
//std::string generateResponse(const std::string& request) {
// // 在此处根据实际需求生成相应的HTTP响应
// std::string response = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
// response += "<html><body><h1>Hello, World!</h1></body></html>";
// return response;
//}
std::string generateResponse(const std::string& request) {
// 在此处根据实际需求生成相应的HTTP响应
std::string response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: text/html\r\n";
response += "Access-Control-Allow-Origin: *\r\n";
//response += "Access-Control-Allow-Origin: http://localhost:8080\r\n"; // 允许http://localhost:8080的请求
response += "Access-Control-Allow-Methods: GET, POST\r\n"; // 允许的请求方法
response += "Access-Control-Allow-Headers: Content-Type\r\n"; // 允许的请求头
response += "\r\n";
response += "<html><body><h1>Hello, World!</h1></body></html>";
return response;
}
int main() {
// 初始化Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "Failed to initialize Winsock." << std::endl;
return -1;
}
// 创建监听套接字
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET) {
std::cerr << "Failed to create server socket." << std::endl;
WSACleanup();
return -1;
}
// 绑定地址和端口
sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET; // IPv4
serverAddress.sin_addr.s_addr = INADDR_ANY; // 使用任意可用地址
serverAddress.sin_port = htons(8080); // 监听端口8080
if (bind(serverSocket, (sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR) {
std::cerr << "Bind failed with error: " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return -1;
}
// 开始监听
if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {
std::cerr << "Listen failed with error: " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return -1;
}
std::cout << "Server started. Waiting for connections..." << std::endl;
while (true) {
// 等待客户端连接
sockaddr_in clientAddress;
int clientAddressSize = sizeof(clientAddress);
SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddress, &clientAddressSize);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "Accept failed with error: " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return -1;
}
std::cout << "Client connected." << std::endl;
// 接收和发送数据
const int bufferSize = 4096;
char requestBuffer[bufferSize];
memset(requestBuffer, 0, sizeof(requestBuffer));
if (recv(clientSocket, requestBuffer, sizeof(requestBuffer), 0) == SOCKET_ERROR) {
std::cerr << "Receive failed with error: " << WSAGetLastError() << std::endl;
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
return -1;
}
std::string request(requestBuffer);
// 解析HTTP请求,获取请求路径等信息
std::string requestPath;
size_t firstSpace = request.find(' ');
size_t secondSpace = request.find(' ', firstSpace + 1);
if (firstSpace != std::string::npos && secondSpace != std::string::npos) {
requestPath = request.substr(firstSpace + 1, secondSpace - firstSpace - 1);
}
std::cout << "Request: " << requestPath << std::endl;
// 生成HTTP响应
std::string response = generateResponse(requestPath);
// 发送HTTP响应
if (send(clientSocket, response.c_str(), response.size(), 0) == SOCKET_ERROR) {
std::cerr << "Send failed with error: " << WSAGetLastError() << std::endl;
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
return -1;
}
// 关闭客户端连接
std::cout << "Client disconnected." << std::endl;
closesocket(clientSocket);
}
// 清理Winsock
closesocket(serverSocket);
WSACleanup();
return 0;
}
test(){
fetch("http://127.0.0.1:8080").then((response: Response) => {
return response.text()
}).then((value) => {
console.log(value);
console.log("dsfasd");
})
}
#include <iostream>
#include <QTcpServer>
#include <QTcpSocket>
#include <QByteArray>
#include <QString>
#include <QCoreApplication>
#include <QDebug>
QString generateResponse(const QString& request) {
// 在此处根据实际需求生成相应的HTTP响应
QString response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: text/html\r\n";
response += "Access-Control-Allow-Origin: *\r\n";
response += "Access-Control-Allow-Methods: GET, POST\r\n";
response += "Access-Control-Allow-Headers: Content-Type\r\n";
response += "\r\n";
response += "<html><body><h1>Hello, World!</h1></body></html>";
return response;
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
// 创建监听套接字
QTcpServer server;
if (!server.listen(QHostAddress::Any, 8080)) {
qDebug() << "Failed to start server." ;
return -1;
}
qDebug() << "Server started. Waiting for connections...";
QObject::connect(&server, &QTcpServer::newConnection, [&]() {
while (server.hasPendingConnections()) {
QTcpSocket* clientSocket = server.nextPendingConnection();
qDebug() << "Client connected." ;
QObject::connect(clientSocket, &QTcpSocket::readyRead, [=]() {
QByteArray requestData = clientSocket->readAll();
QString request(requestData);
// 解析HTTP请求,获取请求路径等信息
QString requestPath;
int firstSpace = request.indexOf(' ');
int secondSpace = request.indexOf(' ', firstSpace + 1);
if (firstSpace != -1 && secondSpace != -1) {
requestPath = request.mid(firstSpace + 1, secondSpace - firstSpace - 1);
}
qDebug() << "Request: " << requestPath;
// 生成HTTP响应
QString response = generateResponse(requestPath);
// 发送HTTP响应
clientSocket->write(response.toUtf8());
clientSocket->flush();
// 关闭客户端连接
qDebug() << "Client disconnected." ;
clientSocket->disconnectFromHost();
});
}
});
return a.exec();
}