Cesanta Mongoose — проблемы при подключении к локальному хосту

У меня возникают проблемы при создании HTTP-сервера с использованием библиотеки веб-сервера Cesanta Mongoose. Проблема, с которой я сталкиваюсь, возникает, когда у меня есть HTTP-сервер, созданный для прослушивания порта 8080, и клиент, отправляющий HTTP-запрос на localhost: 8080. Проблема в том, что сервер нормально обрабатывает запрос и отправляет ответ, но клиент обрабатывает и печатает ответ только после того, как я завершаю серверный процесс. В основном Mongoose работает там, где вы создаете соединения, которые принимают функцию обработчика событий, ev_handler(). Эта функция обработчика событий вызывается всякий раз, когда происходит «событие», например, получение запроса или ответа. На стороне сервера функция обработчика событий вызывается в порядке, когда она получает запрос от клиента на 8080. Однако функция обработчика событий на стороне клиента не вызывается, когда ответ отправляет ответ, а вызывается только после серверного процесса. убит. Я подозревал, что это может быть как-то связано с тем, что соединение идет на localhost, и был прав — такой проблемы не возникает, когда клиент отправляет запросы на адреса, отличные от localhost. Функция обработчика событий называется штрафом. Вот функция ev_handler на стороне клиента для справки:

static void ev_handler(struct mg_connection *c, int ev, void *p) {
  if (ev == MG_EV_HTTP_REPLY) {
    struct http_message *hm = (struct http_message *)p;
    c->flags |= MG_F_CLOSE_IMMEDIATELY;
    fwrite(hm->message.p, 1, (int)hm->message.len, stdout);
    putchar('\n');
    exit_flag = 1;
  } else if (ev == MG_EV_CLOSE) {
    exit_flag = 1;
  };
  }

Является ли это распространенной проблемой при попытке установить соединение на локальном хосте с сервером на том же компьютере?


person ageispolis    schedule 02.12.2019    source источник
comment
Что происходит, когда вы пробуете другие клиенты, например обычный браузер?   -  person larslars    schedule 06.01.2020


Ответы (1)


Причиной такого поведения является тот факт, что клиентское соединение не запускает событие до тех пор, пока не будут прочитаны все данные. Как клиент узнает, что все данные прочитаны? Есть 3 возможности:

  1. Сервер отправил заголовок Content-Length: XXX, а клиент прочитал XXX байт тела сообщения, поэтому он знает, что получил все.
  2. Сервер отправил заголовок Transfer-Encoding: chunked и отправил все фрагменты данных, за которыми следует пустой фрагмент. Когда клиент получает пустой фрагмент, он знает, что получил все.
  3. Сервер не ставил ни Content-Lenth, ни Transfer-Encoding. В этом случае клиент не знает, каков размер тела, и продолжает читать, пока сервер не закроет соединение.

То, что вы видите, это (3). Решение: установите Content-Length в коде вашего сервера.

person valenok    schedule 29.01.2021