10

我正在尝试编写一个处理 GET、POST、HEAD 请求的小型 c++ 网络服务器。我的问题是我不知道如何解析标头、消息正文等。它正在侦听套接字,我什至可以将内容写到浏览器中就好了,但我很好奇我应该如何在 C++ 中做到这一点。

Afaik 一个标准的 GET/POST 请求应该是这样的:

GET /index HTTP/1.1
Host: 192.168.0.199:80
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko)     Chrome/25.0.1364.97 Safari/537.22
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

this is the message body

所有行都以 '\r\n' 结尾。

我是否应该在 '\n' 处拆分请求并修剪它们(如果是这样的话)?另外如何处理帖子数据中的文件?

我想要实现的主要目标是获取包含标题键=> 值对的向量、带有请求方法的字符串、发布数据(如在 PHP 中,如果存在)和查询字符串(例如 /index)作为字符串或由“/”分割的向量。

谢谢!

4

4 回答 4

2

在自己做所有事情之前,我向您介绍Poco

class MyHTTPRequestHandler : public HTTPRequestHandler
{
public:
    virtual void handleRequest(HTTPServerRequest & request,
                               HTTPServerResponse & response) {
        // Write your HTML response in res object
    }
};

class MyRequestHandlerFactory : public HTTPRequestHandlerFactory
{
    MyHTTPRequestHandler handler;

public:
    MyRequestHandlerFactory(){}
    HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
    {
        const string method = request.getMethod();
        if (method == "get" || method == "post")
            return &handler;
        return 0;
    }
};

int main()
{
    HTTPServerParams params;
    params.setMaxQueued(100);
    params.setMaxThreads(16);
    ServerSocket svs(80);
    MyRequestHandlerFactory factory;
    HTTPServer srv(&factory, svs, &params);
    srv.start();
    while (true)
        Thread::sleep(1000);
}
于 2013-03-02T21:06:11.840 回答
2

Boost.Asio 是一个很好的库,但相对低级。你真的很想使用更高级别的库。有一个名为node.native的现代 C++ 库,您应该查看它。一个very server可以实现如下:

#include <iostream>
#include <native/native.h>
using namespace native::http;

int main() {
    http server;
    if(!server.listen("0.0.0.0", 8080, [](request& req, response& res) {
        res.set_status(200);
        res.set_header("Content-Type", "text/plain");
        res.end("C++ FTW\n");
    })) return 1; // Failed to run server.

    std::cout << "Server running at http://0.0.0.0:8080/" << std::endl;
    return native::run();
}

没有比这更简单的了。

于 2013-04-19T15:44:40.080 回答
1

是的,这基本上只是字符串解析,然后按照规范创建返回到浏览器的响应。

但是,如果这不仅仅是一个爱好项目,并且您不想承担非常大的任务,那么您应该使用 Apache,如果您需要一个需要扩展的 Web 服务器,或者tntnet,如果您需要一个 C++ Web 框架,或者cpp-netlib如果你需要 C++ 网络的东西。

于 2013-03-02T21:10:51.777 回答
1

您可能需要考虑Proxygen,Facebook 的 C++ HTTP 框架。它是在 BSD 许可下开源的。

于 2014-11-19T16:22:08.020 回答