I want to broadcast OpenCV images (coming from a camera) to a distant computer in real time, it has to be done via Ethernet. The images are continuously received in standard OpenCV Mat objects. The final code has to be integrated into a C++ (Qt) application.

I have found [this Python script](https://gist.github.com/n3wtron/4624820) that does the job very well.

Now I'm trying to get a C++ equivalent of that code, I managed to create an HTTP server using Boost Asio and the [Simple-Web-Server](https://github.com/eidheim/Simple-Web-Server) project. I am able to display a [static blue image](https://github.com/VictorLamoine/Simple-Web-Server/blob/master/http_example.cpp)/webcam camera image (not refreshed).

I have written a code but it's not working. My guess is that the data are sent only at the return of the function (which never returns).
How can I force sending the data after each iteration of the while loop?

```
#include "server_http.hpp"

#include <thread>
#include <boost/chrono.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <opencv2/opencv.hpp>
//#include <opencv/cv.h>

using namespace boost::posix_time;
typedef SimpleWeb::Server<SimpleWeb::HTTP> HttpServer;

cv::Mat image;
cv::VideoCapture cap;

int main()
{
  cap.open(0);
  if (!cap.isOpened ())
  {
    std::cerr << "Could not initialize capturing" << std::endl;
    return (-1);
  }
  cap >> image;

  HttpServer server(8080, 2);

  // Image resource is requested
  server.resource["^/cam.mjpg"]["GET"] =
      [=](HttpServer::Response& response, std::shared_ptr<HttpServer::Request> request)
      {
        time_facet *facet = new time_facet("%d-%b-%Y %H:%M:%S");
        std::cout.imbue(std::locale(std::cout.getloc(), facet));
        std::cout << second_clock::local_time() << " | " << "Camera image requested!" << std::endl;

        response <<
        "HTTP/1.1 200 OK\r\n"
        "Content-type: multipart/x-mixed-replace; boundary=--jpgboundary";
        //TODO: Send header

        while (1) // TODO: Allow exiting this
        {
          std::cout << "Send image" << std::endl;
          cap >> image;
          // Encode mat to jpg and copy it to content
          std::vector<uchar> buf;
          cv::imencode(".jpg", image, buf, std::vector<int>());
          std::string img_content(buf.begin(), buf.end());

          response << "--jpgboundary\r\n" << // Signal we start a new image
              "Content-type: image/jpeg" <<
              "Content-Length: " << img_content.length() << "\r\n" <<
              "\r\n" << img_content << "\r\n";
          std::this_thread::sleep_for(std::chrono::milliseconds(400));
        }
      };

  // Anything else is requested
  server.default_resource["GET"] = [](HttpServer::Response& response, std::shared_ptr<HttpServer::Request> request)
  {
    time_facet *facet = new time_facet("%d-%b-%Y %H:%M:%S");
    std::cout.imbue(std::locale(std::cout.getloc(), facet));
    std::cout << second_clock::local_time() << " | " << request->path << std::endl;

    std::string content =
    "<html><head></head><body>"
    "<img src=\"cam.mjpg\"/>"
    "</body></html>";
    response <<
    "HTTP/1.1 200 OK\r\n"
    "Content-Length: " << content.length() << "\r\n"
    "\r\n" << content;
  };

  std::thread server_thread([&server]()
  {
    server.start();
  });

  std::this_thread::sleep_for(std::chrono::seconds(1));
  server_thread.join();
  return 0;
}

```

---

**EDIT 1**

Based on Technik Empire comment I went back to [boost examples](http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/examples/cpp11_examples.html);
In the HTTP server example the response in sent when the callback returns so I modified the callback to allow [`do_write()`](https://github.com/VictorLamoine/Simple-Web-Server/blob/boost_example/connection.cpp#L72-L91) operations on the socket.

The HTML page is correctly displayed but the image is not displayed (the broken image icon is shown instead), I tried to see what happens with Wireshark but I don't know what is wrong.

Here is my handle\_request function: ([request\_handler.cpp](https://github.com/VictorLamoine/Simple-Web-Server/blob/boost_example/request_handler.cpp#L32-L111)):

```
void request_handler::handle_request(const request& req, reply& rep, connection &con)
{
  // Decode url to path.
  std::string request_path;
  if (!url_decode(req.uri, request_path))
  {
    rep = reply::stock_reply(reply::bad_request);
    return;
  }

  // Request path must be absolute and not contain "..".
  if (request_path.empty() || request_path[0] != '/'
      || request_path.find("..") != std::string::npos)
  {
    rep = reply::stock_reply(reply::bad_request);
    return;
  }

  // Determine the file extension.
  std::size_t last_slash_pos = request_path.find_last_of("/");
  std::string filename;
  if (last_slash_pos != std::string::npos)
    filename = request_path.substr(last_slash_pos + 1);

  if (filename == "cam.mjpg") // Image is requested
  {
    rep.status = reply::ok;
    rep.headers.resize(1);
    rep.headers[0].name = "Content-Type";
    rep.headers[0].value = "multipart/x-mixed-replace; boundary=--jpgboundary";
    rep.content.empty();
    con.do_write();
    rep.status = reply::none;

    while (true) // FIXME: How do I handle disconnection from the client?
    {
      cv::Mat image(200, 300, CV_8UC3);
      int random = rand() % 255 + 1;
      image = cv::Scalar(random, 0, 0); // Fill image with blue
      std::vector<uchar> buf;
      cv::imencode(".jpg", image, buf, std::vector<int>());
      std::string img_content(buf.begin(), buf.end());

      rep.headers.clear();
      rep.content.clear();

      rep.content.append("--jpgboundary\r\n");
      con.do_write();

      rep.content.clear();
      rep.headers.resize(2);
      rep.headers[0].name = "Content-Type";
      rep.headers[0].value = mime_types::extension_to_type("jpg");
      rep.headers[1].name = "Content-length";
      rep.headers[1].value = img_content.size();
      rep.content.append(img_content);
      rep.content.append("\r\n");
      con.do_write();

      boost::this_thread::sleep(boost::posix_time::milliseconds(500));
    }
  }
  else // Anything but the image is requested
  {
    std::string content =
    "<html><head></head><body>"
    "Hello :)<br>"
    "<img src=\"cam.mjpg\"/>"
    "</body></html>";

    rep.status = reply::ok;
    rep.headers.resize(2);
    rep.headers[0].name = "Content-Length";
    rep.headers[0].value = content.length();
    rep.headers[1].name = "Content-Type";
    rep.headers[1].value = mime_types::extension_to_type("html");
    rep.content.append(content);
    con.do_write();
    return;
  }
}

```