2010-03-03 1 views
1

У меня есть приложение, которое будет работать как p2p-программное обеспечение, где все одноранговые узлы будут разговаривать друг с другом. Поскольку связь будет TCP, я думал, что могу использовать epool(4), чтобы можно было обрабатывать несколько соединений. Поскольку каждый одноранговый узел будет отправлять данные очень часто, я думал, что установил постоянное соединение с каждым одноранговым узлом, который будет использоваться в течение срока службы приложений.Работа с данными по нескольким TCP-соединениям с epoll

Теперь, одна вещь, с которой я не знаю, как обращаться, заключается в том, что, поскольку соединение никогда не закрывается, как я узнаю, когда я должен прекратить прием данных с помощью read() и позвонить epool_wait() еще раз, чтобы прослушать больше пакетов? Или есть лучший способ борьбы с постоянными TCP-соединениями?

+0

Просто из любопытства: почему epoll (BTW: это не «epool»), а не обычный опрос или выбор (оба гораздо более портативные, я думаю)? –

ответ

2

Вы должны установить сокет неблокируемой, и когда Epoll указывает на наличие данных для чтения вы должны позвонить читать() в цикле до чтения() возвращает -1 и ERRNO является EWOULDBLOCK

То есть , ваш цикл чтения может выглядеть sometihng как:

for(;;) 
    ssize_t ret; 
    ret = read(...); 
    if(ret == 0) { 
    //client disconnected, handle it, remove the fd from the epoll set 
     break; 
    } else if(ret == -1) { 
    if(errno == EWOULDBLOCK) { 
     // no more data, return to epoll loop 
     } else { 
     //error occured, handle it remove the fd from the epoll set 
     } 
     break; 
    } 

// handle the read data 
} 

Если вы не используете край режим с Epoll срабатывает, вы на самом деле не нужны петли - вы могли бы уйти с делать только 1 чтение и вернуться к epoll loop. Но обрабатывайте возвращаемые значения так же, как приведенный выше код.

+0

В качестве альтернативы вы можете использовать 'recv' вместо' read' и поставлять флаг 'MSG_DONTWAIT'. Не забывайте также об обработке 'SIGPIPE'. – caf

+0

'if ((EWOULDBLOCK == errno) || (EAGAIN == errno))', сделать его более переносимым в других системах Unix. :-) – zeekvfu

0

read() считывает как можно больше данных, которые доступны (но не более того, что вы запрашиваете). Просто запустите read() в активном сокете с достаточно большим буфером (вам, вероятно, не нужно больше, чем ваш MTU ... 2048 байт будет делать) и вызовите epoll_wait(), когда он будет завершен.

1

Это должно быть «epoll», а не «epool» ... не знакомы с epoll, но посмотрите здесь, на Beej's guide, чтобы увидеть пример сокетов с помощью «poll» ... посмотреть раздел 7.2, чтобы посмотреть, как это делается, также посмотрите раздел 9.17 на использование «опроса» ...

Надеюсь, это поможет, С уважением, Том.

+0

Да, это была опечатка от меня :) Спасибо за ссылку. – DeeD

 Смежные вопросы

  • Нет связанных вопросов^_^