The code is very much based on the boost "blocking tcp echo server" example.
My idea is that the code above, when accessed from a web browser at localhost:3333 would give one printout for each time I (re)load the URL.
I also expected exactly 3 printouts.
However, I do not always get exactly 3 printouts. Sometimes it's just 2, sometimes it's 4...
Note that you are detaching the created thread. That means that the OS is not required to wait for that thread to finish before shutting down the entire process.
If you want to wait for all processes to finish before main() can return, you can do
1 2 3 4 5 6
std::vector<std::thread> threads;
//in the loop:
threads.emplace_back(accept_handler, std::move(tcp_socket));
//after the loop:
for (auto &t : threads)
t.join();