【问题标题】:Simple HTTP server failing with "connection redefined"简单的 HTTP 服务器因“重新定义连接”而失败
【发布时间】:2017-07-17 14:05:07
【问题描述】:

基于 boost 的示例,我编写了以下程序。它应该使用 HTTP 200 和一个小文本来回答连接:

#include <iostream>
#include <sstream>
#include <boost\asio.hpp>
#include <ctime>
using namespace std;
using boost::asio::ip::tcp;
int main(int argc, char** argv)
{
    try
    {
        boost::asio::io_service io_service;
        tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 40001));
        while (true)
        {
            tcp::socket socket(io_service);
            acceptor.accept(socket);
            //Aceitou uma conexao
            time_t now = time(0);
            stringstream ssHtml;
            ssHtml << "HELLO WORLD ";
            stringstream ssHttp;
            ssHttp << "HTTP/1.1 200 OK\r\n";
            ssHttp << "Connection: close\r\n";
            ssHttp << "Content-Type: text/html\r\n";
            ssHttp << "Content-Length: " << ssHtml.str().size() <<"\r\n";
            ssHttp << ssHtml.str();
            ssHttp << "\r\n\r\n";
            boost::system::error_code ignored_error;
            cout << ssHttp.str();
            boost::asio::write(socket, boost::asio::buffer(ssHttp.str()), ignored_error);
        }
    }
    catch (std::exception &ex)
    {
        cerr << ex.what() << endl;
    }
    return 0;
}

但是浏览器的请求失败并出现“重新定义的连接”。在调试服务器时,我看到它成功运行,将 http 响应打印到它的控制台。

在 Firefox 的开发者模式下,我看到响应到达,但由于某种原因,浏览器说连接已被重新定义。由于某种原因,浏览器在服务器上连接了两次,两次都失败了。 另外,防火墙是开放的,端口是空闲的。

我的问题是:我做错了什么?为什么这个简单的服务器不响应请求?为什么浏览器会出现“重新定义连接”错误?

【问题讨论】:

  • 我注意到的两个问题:最后一个标题(“Content-length”)应该以 2 个换行符结尾,标记标题的结尾,不需要内容后的 2 个换行符;第二:您可能还应该从浏览器读取请求。

标签: c++ http boost boost-asio


【解决方案1】:

HTTP 协议需要双行尾来标记响应标头的结尾。至少添加一个:

        ssHttp << "\r\n" << ssHtml.str();

而且,您可能还希望避免在内容数据之后发送无关的行尾(尽管使用 Connection: close 标头,差异应该不会很明显)。

【讨论】:

    【解决方案2】:

    当我从浏览器读取请求时,正如 ChrisBFX 在上面的评论中所建议的那样,我的服务器或多或少地按预期工作。响应被发送到浏览器并且浏览器理解它。它仍然发送两个响应而不是一个,但它不再因“连接重定向”而失败。

    #include <iostream>
    #include <sstream>
    #include <boost\asio.hpp>
    #include <ctime>
    using namespace std;
    using boost::asio::ip::tcp;
    int main(int argc, char** argv)
    {
        try
        {
            boost::asio::io_service io_service;
    
            tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 40001));
            while (true)
            {
                tcp::socket socket(io_service);
                acceptor.accept(socket);
    /////////////-------------THIS SOLVED THE PROBLEM----------------------
                boost::asio::streambuf s_buf;
                boost::asio::async_read_until(socket, s_buf, "\r\n\r\n",
                    std::bind([](const boost::system::error_code& ec){
                    if (ec != 0)
                        std::cout << "error " << ec.value() << ", " << ec.message();
                    }, 
                    std::placeholders::_1));
                std::string message;
                std::istream input_stream(&s_buf);
                std::getline(input_stream, message);
                std::cout << message << std::endl;
    ///////////////------------------------------------------------------
                time_t now = time(0);
                stringstream ssHtml;
                ssHtml << "HELLO WORLD ";
                stringstream ssHttp;
                ssHttp << "HTTP/1.1 200 OK\r\n";
                ssHttp << "Connection: close\r\n";
                ssHttp << "Content-Type: text/html\r\n";
                ssHttp << "Content-Length: " << ssHtml.str().size();// << "\r\n";
                ssHttp << "\r\n\r\n";
                ssHttp << ssHtml.str();         
                boost::system::error_code ignored_error;
                cout << ssHttp.str();
                boost::asio::write(socket, boost::asio::buffer(ssHttp.str()), ignored_error);
            }
        }
        catch (std::exception &ex)
        {
            cerr << ex.what() << endl;
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-29
      • 1970-01-01
      相关资源
      最近更新 更多