2016-07-11 10 views
0

소켓을 사용하여 포트 열기 테스트를 작성하려고하는데 잘못된 IP 주소에 대해 "포트 열기"가보고되는 이유가 있습니다. 현재 인터넷에 연결되어 있지 않은 액세스 포인트에 연결되어 있으므로 외부 IP 주소에 대해 포트가 잘못보고되고 있습니다.C 소켓/폴링이 POLLOUT 이벤트를 잘못 반환합니까?

먼저 소켓을 설정하고 비 차단 모드이므로 대개 첫 번째 if 문에 의해 진행됩니다. 그런 다음 소켓을 폴링합니다. 그러나 외부 IP에있는 소켓의 경우 POLLOUT 이벤트가 발생하는 경우에도 문제가 발생하지는 않습니다 ...

무엇이 없습니까? 설문 조사에 수신 된 이벤트에 POLLOUT이 포함 된 이유는 무엇입니까? poll을 다시 호출하기 전에 구조체 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가 발생하지 않으면 select 루프를 입력하면 안됩니다. 'poll()'은 EINPROGRESS를 발생시키지 않습니다. 이걸 정리하고 다시 시도해야합니다. 또한 EPOLLOUT을 얻을 때 소켓 FD에서 SO_ERROR를 확인해야합니다. – EJP

+0

@EJP 당신 말이 맞아요. 논쟁에 대한 나의 대답과 사과를 삭제했습니다. 나는 더 많은 독서와 실험을 수행했으며 나의 모범이 잘못되었다고 결론 지었다. 어쨌든, 고맙습니다, 오늘 뭔가 배웠습니다! – pah

+0

@EJP 내 편집을 참조하십시오. 오류 검사를 제거하고 EPOLLOUT 후 SO_ERROR를 확인했습니다. – kburbach

답변

0

POLLOUT 이벤트를 수신 한 후 SO_ERROR를 확인해야합니다. 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);