2013-02-25 2 views
1

Iam хочет написать программу сокетов на основе libev. Я заметил, что несколько примеров, указанных в https://github.com/coolaj86/libev-examples/blob/master/src/unix-echo-server.c, используют обратные вызовы на основе init. Например,розетки с использованием libev

main() { 

...... 
ev_io_init(&client.io, client_cb, client.fd, EV_READ|EV_WRITE); 
ev_io_start(EV_A_ &server.io); 

} 

static void client_cb (EV_P_ ev_io *w, int revents) 
{ 
    if (revents & EV_READ) 
    { 
     .... 
    } else if (revents & EV_WRITE) { 

    ...... 
    } 
} 

Мой вопрос исходит от ожидаемого поведения, скажем, к примеру, все, что я читал, когда в EV_READ хранится в связанном списке. Допустим, я продолжаю читать свободный поток пакетов, я когда-нибудь получу шанс попасть в EV_WRITE? Я должен отправить все, что я получаю, через чтение в другой сокет. Так будет ли это когда-то EV_READ и второй раз EV_WRITE? Другими словами, когда EV_WRITE будет разблокирован? Или мне нужно заблокировать EV_READ для вызова EV_WRITE. Может кто-нибудь помочь мне понять это?

+0

http://codefundas.blogspot.com/2010/09/create-tcp-echo-server-using-libev.html – enthusiasticgeek

ответ

2

Чтобы ответить коротко: Если вы все время сначала проверяете один тип события, а затем имеете else if, то для другого вы рискуете голодом. В общем, я бы проверял оба, если только указанный протокол не позволяет одновременно активировать оба.

Вот еще более точный ответ: Ссылка на ваш вопрос не содержит структуры кода, например, вашего вопроса. Клиент https://github.com/coolaj86/libev-examples/blob/master/src/unix-echo-client.c имеет аналогичный обратный вызов. Вы заметите, что он отключает запись событий, когда он написал один раз.

// once the data is sent, stop notifications that 
// data can be sent until there is actually more 
// data to send 
ev_io_stop(EV_A_ &send_w); 
ev_io_set(&send_w, remote_fd, EV_READ); 
ev_io_start(EV_A_ &send_w); 

Это похоже на попытку избежать голодания ветви события READ. Несмотря на то, что я не очень хорошо знаком с libev, приведенные ниже примеры github не очень надежны. Например, static void stdin_cb (EV_P_ ev_io *w, int revents) не использует возвращаемое значение getline() для обнаружения EOF. Кроме того, значения возвращаемых значений сокета send() и recv() не проверяются на то, сколько было прочитано или записано (хотя в локальных именованных потоках потоков суммы, скорее всего, будут соответствовать запрошенным суммам). Если впоследствии это было изменено на TCP-соединение, проверка количества будет жизненно важной.

+0

Да Я знаю, что код, который я использую для понимания, не очень хорош, но я буду очень рад, если вы можете указать мне на любой другой. Итак, из того, что вы говорите, если я проверю оба, я должен быть хорошим, чтобы идти и избегать голода. Благодарю. – user2085689

+0

Да, проверьте оба. Используйте 'if()' statement вместо 'if-else'. – thuovila

1

Я думаю, что вы должны держать записи обратного вызова, отделенный от чтения обратного вызова:

main() { 
    ev_io_init(&read.io, read_cb, client.fd, EV_READ); 
    ev_io_init(&write.io, writead_cb, client.fd, EV_WRITE); 
    ev_io_start(EV_A_ &read.io); 
    ev_io_start(EV_A_ &write.io); 
} 

Это мое решение.