Libevent Buffrevent сокет флеш

Я буду держать коротко. Как очистить данные, ожидающие в bufferevent выходной буфер прямо в сокет блокирующим образом.

После закрытия моего класса оболочки сокета после выполнения асинхронной записи (используя evbuffer_add), Либивент выплевывает epoll ошибки, указывающие на то, что была предпринята попытка записи на недействительный fd. Мне нужно иметь возможность сбрасывать ожидающие данные libevent в сокет, какие-либо предложения?

Примечание: специфическая ошибка: Epoll MOD (4) на fd 9 не удалось. Старые события были 6; изменение чтения было 2 (del); изменение записи было 0 (нет): неверный дескриптор файла.

0

Решение

Вы пытались отключить задержку сокета? Отключение задержки сокета заставляет сокет не ждать неотправленных данных перед закрытием сокета.

struct linger linger;
memset(&linger, 0, sizeof(struct linger));
retVal = setsockopt(sock, SOL_SOCKET, SO_LINGER, (const void*)&linger, sizeof(struct linger));
2

Другие решения

Для любого из тех, кто может столкнуться с той же ошибкой, я обнаружил, в чем заключается моя проблема — спасибо Инге Хенриксен.

class ASocket
{

// ...

~ASocket()
{
if(m_handle.bev)
{
bufferevent_free(m_handle.bev);
}

if(m_handle.fd >= 0)
::close(m_handle.fd);
}

// ...
}

После удаления асинхронного объекта сокета (ASocket), bufferevent будет освобожден, если он существует, и сокет будет удален — libevent продолжит работать на закрытом сокете. Обратите внимание, что bufferevent_free, как указано в http://www.wangafu.net/~nickm/libevent-book/Ref6_bufferevent.html#_freeing_a_bufferevent, но не на странице документации Doxygen, не освободит bufferevent по вызову bufferevent_free функция, а скорее:

Однако функция bufferevent_free () пытается освободить буфер как можно скорее.

Это было исправлено так:

class ASocket
{

// ...

// If bufferevent exists, it must be created with
// the BEV_OPT_CLOSE_ON_FREE flag.
~ASocket()
{
if(m_handle.bev)
{
bufferevent_free(m_handle.bev);
}
else
{

if(m_handle.fd >= 0)
::close(m_handle.fd);
}
}

// ...
}

Если розетка имеет bufferevent, он освобождается и libevent закроет сокет, как только он будет завершен.

2

Я не мог сделать это внутри самого обратного вызова, но это можно сделать с помощью другого обратного вызова, см. https://github.com/libevent/libevent/blob/master/sample/le-proxy.c

if (partner) {
/* Flush all pending data */
readcb(bev, ctx);

if (evbuffer_get_length(
bufferevent_get_output(partner))) {
/* We still have to flush data from the other
* side, but when that's done, close the other
* side. */
bufferevent_setcb(partner,
NULL, close_on_finished_writecb,
eventcb, NULL);
bufferevent_disable(partner, EV_READ);
} else {
/* We have nothing left to say to the other
* side; close it. */
bufferevent_free(partner);
}
}
0
По вопросам рекламы [email protected]