2015-10-24 3 views
0

У вас возникли проблемы с получением данных через epoll из ответов в клиентском приложении.Tcp клиент с epoll на linux. Событие EPOLLIN не связано с несколькими подключениями

I'v сделал простой код иллюстрации. Максимальная логика обработки ошибок.

Краткое описание контекста:

  1. клиентское приложение создает 2 неблокирующих сокетов (SOCK_NON_BLOCK передается сокет, а не через FCNTL)
  2. клиент добавлять сокеты к событиям с EPOLLOUT | EPOLLONESHOT и звонки подключаются к каждому сокету (без блокировки, поэтому я получаю EINPROGRESS) клиент ждет с epoll_wait для установления соединения (wait for EPOLLOUT)
  3. при подключении - отправляет 1 запрос пакета (для иллюстрации я сделал HEAD-запросы с помощью хоста example.com на google.com серверы)
  4. , когда отправлено возвращает Epoll уведомляет фильтры перешли на EPOLLIN
  5. клиент ожидает данные для чтения (если не EAGAIN) и закрывает сокет после того, как первый фрагмент (его прочитанные OK)

Задача:

только один гнездо получает нитификация, ответ пришел.

В ТСРйитре я вижу, что веб-сервера отправляют оба ответа ( Вот ТСРйитр с выделенными как ответами от серверов. Так как запрос принят и ответов пришел http://pastie.org/10504786#59-78,89-109 )

I'v готовил максимально простой пример с два жестко закодированных google ips (для простоты пропустить имя resolv).

Кажется код немного огромно для поста, так например, здесь: http://pastie.org/10504718

Вот компилировать и вывод:

% gcc -std=c99 -Wall ./main.c && ./a.out 
assigned 4 for 173.194.32.135 
assigned 5 for 173.194.32.130 
socket 4 
    write event 
    data send 35 via 4 
socket 5 
    write event 
    data send 35 via 5 
socket 5 
    read event 
    read returned 258 <-- we have answer from first 
socket 5 
    read event 
    read returned 4294967295 
    read errno =9 errmesg= Bad file descriptor <--its ok cause we closed fd,but seems its event cached event 

Один кот см 2 соединения установлены, и два запроса послал, но читать событие запускается только для одного сокета.

Невозможно получить то, что относится к такому поведению, конфигурация сокетов кажется независимой.

ответ

0

Позор на меня.

Ошибка была в неправильной инициализации данных событий. Я забыл переназначить указатель на связанную структуру при переходе на IN. Таким образом, все коммутаторы указывали на одни и те же данные.

код ошибки

//switching data listen 
    ev.events = EPOLLIN | EPOLLONESHOT; 
    epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev); 

(http://pastie.org/10504718#83-85)

должен быть

//switching data listen 
    ev.data.ptr = c; 
    ev.events = EPOLLIN | EPOLLONESHOT; 
    epoll_ctl(epfd, EPOLL_CTL_MOD, c->fd, &ev);