简单HTTP服务器失败,“连接已重新定义”

时间:2017-07-17 14:05:08

标签: c++ http boost boost-asio

根据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的devloper模式中,我看到响应到了,但由于某种原因,浏览器说连接已被重新定义。出于某种原因,浏览器在服务器上连接两次并且两次都失败。 此外,防火墙已打开,端口是免费的。

我的问题是:我做错了什么?为什么这个简单的服务器没有回答请求?为什么浏览器因“连接重新定义”错误而失败?

2 个答案:

答案 0 :(得分:0)

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

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

并且,您可能希望避免在内容数据之后发送无关的行结束(尽管使用Connection: close标题,差异不应该非常明显)。

答案 1 :(得分:0)

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

#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;
}