2013-11-18 5 views
1

На основании следующего кода я построил версию сервера эха, но с задержкой с потоком. Это было построено, потому что я заметил, что при первом подключении моя первая передача отправляется обратно клиенту, но клиент не получает его до второй отправки. Мой реальный случай использования заключается в том, что мне нужно отправлять сообщения на сервер, выполнять большую обработку, а затем отправлять результат обратно ... скажем, через 10-30 секунд (может быть часы в некоторых случаях).Libevent не срабатывает должным образом, когда есть задержка

http://www.wangafu.net/~nickm/libevent-book/Ref8_listener.html

Так вот мой код. Для краткости я включил только код, посвященный libevent; а не код нитей или другие вещи. При отладке настраивается новое соединение, буфер строки заполняется должным образом, и отладка показывает, что записи успешно завершены.

http://pastebin.com/g02S2RTi

Но я только получить эхо от посыла до того, в последний раз. Я отправляю с номеров клиентов, чтобы проверить это, и когда я отправляю 1 из клиента, я ничего не получаю от сервера через echo ... хотя сервер определенно записывается в буфер с помощью evbuffer_add (я также пробовал это с помощью bufferevent_write_buffer).

От клиента, когда я отправляю 2, я получаю 1 от предыдущей отправки. Это похоже на то, что мои записи кэшируются ... Я отключил нагло.

Итак, мой вопрос: отправляет ли libevent-кеш следующим образом?

evbuffer_add (outputBuffer, buffer, length);

Есть ли способ сбросить этот кеш? Есть ли какой-либо другой метод, чтобы пометить кеш как завершенный или завершенный? Могу ли я заставить отправить? Он никогда не посылает на себя ... Я даже задерживаю. Замена evbuffer_add на «send» отлично работает каждый раз.

ответ

1

Скорее всего вас затронул Nagle algorithm - в основном он буферизует исходящие данные, прежде чем отправлять их в сеть. Взгляните на эту статью: TCP/IP options for high-performance data transmission.

Вот пример того, как отключить буферизацию:

int flag = 1; 
int result = setsockopt(sock,   /* socket affected */ 
         IPPROTO_TCP,  /* set option at TCP level */ 
         TCP_NODELAY,  /* name of option */ 
         (char *) &flag, /* the cast is historical 
               cruft */ 
         sizeof(int)); /* length of option value */ 
+0

Да, я пробовал. Оказывается, нарезка была большой проблемой. Добавив следующее к началу моего основного, до создания libevent, все работало нормально. evthread_use_windows_threads(); (pthread для linux) –