Why does my simple HTTP server implemented using Boost.ASIO require sleep to work correctly

I am trying to write a very simple HTTP server using Boost.Asio. Here is the code (almost the same as in the example from the Boost.Asio tutorial)

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <thread>
#include <chrono>

using boost::asio::ip::tcp;

int main()
{
    try
    {
        boost::asio::io_service io_service;

        tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 12345));

        for (;;)
        {
            tcp::socket socket(io_service);
            acceptor.accept(socket);

            const char message[] = "HTTP/1.0 200 OK\r\n\r\n<html><body><i>Hello, world</i></body></html>";

            boost::system::error_code ignored_error;
            boost::asio::write(socket, boost::asio::buffer(message), ignored_error);
        }
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}

When I run this sample, I try to use Chrome at 127.0.0.1:12345, but it shows "This webpage is not available." But if I start in the debugger and step by step, it correctly displays the highlighted in italics "Hello, world". In fact, it will work correctly if you add a line after a write operation std::this_thread::sleep_for(std::chrono::seconds(1));. What am I doing wrong? Is there any way to avoid this ugly hack?

I am using Visual Studio 2013 on Windows 7. Compiled as 64-bit code.

+4
3

, - HTTP, .

Content-Length, HTTP/1.1 (Chrome), , , , , . rfc2616 4.4. :

  "HTTP/1.0 200 OK\r\nContent-Length: 45\r\n\r\n<html><body><i>Hello, world</i></body></html>";

, Content-Length .;)

+2

, Content-Length , .

, Connection: close, (, "EOF" ).


, (Ubuntu/Opera).

, ... ,

  • NUL :

    $ netcat localhost 12345 | xxd
    0000000: 4854 5450 2f31 2e30 2032 3030 204f 4b0d  HTTP/1.0 200 OK.
    0000010: 0a0d 0a3c 6874 6d6c 3e3c 626f 6479 3e3c  ...<html><body><
    0000020: 693e 4865 6c6c 6f2c 2077 6f72 6c64 3c2f  i>Hello, world</
    0000030: 693e 3c2f 626f 6479 3e3c 2f68 746d 6c3e  i></body></html>
    0000040: 00                                       .
    
  • ; (?). , , , .

, / , (, GET /favicon.ico, , . , . , , 1 (, , , 10) "backlog"

('08) , backlog 5 Asio.

+3

, , . , reset. , , .

Your example does not work with a delay trick if I add a listening request for authentication immediately before recording:

std::array<char, 8192> ignored_buffer;
socket.async_read_some(boost::asio::buffer(ignored_buffer),
    [](boost::system::error_code ec, std::size_t bytes_transferred) {});
0
source

Source: https://habr.com/ru/post/1537479/


All Articles