2015-07-27 3 views
2

Мне интересно, как libevent запускает обратный вызов. Например, предположим, что клиент повторно отправляет 4-байтовое сообщение. На стороне сервера, кажется, не каждая 4-байтовая передача вызовет обратный вызов чтения. Например, я обнаружил, что обратный вызов иногда запускается в точке получения 8-байтового сообщения (или другого номера). Можно ли настроить libevent таким образом, чтобы обратный вызов чтения на стороне сервера запускался для каждого 4-байтового сообщения, отправленного с клиента?Как libevent вызывает обратный вызов

ответ

2

Я считаю, что ваша проблема касается отправки, а не о получении. Libevent, вероятно, не отправляет ваши данные немедленно из-за вывод буферизации, при этом ваш обратный вызов read вызывается только тогда, когда клиент действительно получает данные, которые вы отправили.

См. Nagle's algorithm (aka TCP_NODELAY). Затем попробуйте отключить его, чтобы увидеть, если это действительно так:

int flag = 1; 
int ret = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)); 

Можно ли настроить Libevent такое, что чтение обратного вызова на стороне сервера срабатывает для каждого сообщения 4 байт, посланного от клиента?

Не совсем. Вы можете получать несколько сообщений «одновременно», поскольку TCP является потоковым протоколом. Единственное, что касается вашего приложения, это знать, где начинается и заканчивается каждое сообщение.

Игнорирование Libevent с целью объяснения, вы обычно:

  1. Keep вызова recv в цикле;
  2. Добавить полученные данные/полезную нагрузку в буфер;
  3. Вызвать метод обработки этого буфера;
  4. Метод процесса проверяет размер буфера, чтобы узнать, содержит ли он как минимум 1 сообщение. В вашем случае вы хотите, чтобы оно составляло не менее 4 байтов, поэтому вы знаете, что у вас есть как минимум 1 полное сообщение для обработки. Если ваш буфер имеет размер, который не кратен 4 байтам (что никогда не должно происходить при очень малом размере вашей полезной нагрузки), скажем, 10 байт, вы обрабатываете начальные 4 байта, удаляете их из буфера, повторяете еще раз и затем сохраните оставшиеся 2 байта в буфере.
+0

Я вижу. Возможно ли, чтобы сервер получил сообщение с размером не кратным 4? – Jes

+1

Помните, что ваша полезная нагрузка составляет ровно 4 байта, тогда ответ НЕТ, но, конечно, я не рекомендую полагаться на это. Вам лучше использовать механизм для хранения полученных данных (см. [Bufferevent's] (http://www.wangafu.net/~nickm/libevent-book/Ref6_bufferevent.html)), а затем обработать его. Если вы обнаружите, что не получили полного сообщения, вы должны просто ждать большего. – jweyrich

+0

Спасибо! Это имеет смысл. – Jes