2016-07-11 8 views
0

Я пытаюсь написать тест открытого порта с помощью сокетов, и по какой-то причине он сообщает «открыть порт» для недопустимых IP-адресов. В настоящее время я подключен к точке доступа, которая не подключена к Интернету, поэтому это неверно сообщает порт, открытый для внешних IP-адресов.C Socket/Опрос неверно возвращается событие POLLOUT?

Сначала я установил гнездо, и поскольку это неблокирующий режим, он, как правило, все еще выполняется первым оператором if. Затем я просматриваю сокет. Однако для сокета на внешнем IP-адресе я получаю событие POLLOUT, хотя это не представляется возможным ...

Что мне не хватает? Почему в опросах, полученных событиях, содержится POLLOUT? Я попытался сбросить структуру pollfd перед вызовом опроса, но это не изменило результат.

result = connect(sd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)); 

if(result == 0) //woohoo! success 
{ 
    //SUCCESS! 
    return true; 
} 
else if (result < 0 && errno != EINPROGRESS) //real error 
{ 
    //FAIL 
    return false; 
} 

// poll the socket until it connects 
struct pollfd fds[1]; 
fds[0].fd = sd; 
fds[0].events = POLLOUT | POLLRDHUP | POLLERR | POLLNVAL; 
fds[0].revents = 0; 

while (1) 
{ 
    result = poll(fds, 1, 1); 

    if (result < 1) 
    { 
     //Poll failed, mark as FAIL 
    } 
    else 
    { 
     // see which event occurred 
     if (fds[0].revents & POLLOUT || fds[0].revents & POLLRDHUP) 
     { 
      //SUCCESS 
     } 
     else if (fds[0].revents & POLLERR || fds[0].revents & POLLNVAL) 
     { 
      //FAIL 
     } 
    } 
} 
+0

Я не сумасшедший относительно структуры кода и проверки ошибок здесь. Если соединение выполнено успешно или не вызывает EINPROGRESS, вы не должны вводить цикл выбора вообще; и 'poll()' не вызывает EINPROGRESS. Вам нужно очистить его и повторить попытку. Вы также должны проверить SO_ERROR на сокете FD, когда вы получаете EPOLLOUT. – EJP

+0

@ EJP, вы правы. Удалил мой ответ и мои извинения за аргументы. Я продолжил чтение и эксперименты и пришел к выводу, что мой пример был испорчен. В любом случае, спасибо, сегодня чему-то научились! – pah

+0

@EJP см. Мое редактирование. Я очистил проверку ошибок, и теперь я проверяю SO_ERROR после EPOLLOUT – kburbach

ответ

0

Мне нужно было проверить SO_ERROR после получения события POLLOUT - сам по себе POLLOUT не указывает на успех.

//now read the error code of the socket 
int errorCode; 
uint len = sizeof(errorCode); 
result = getsockopt(fds[0].fd, SOL_SOCKET, SO_ERROR, 
       &errorCode, &len);