2009-05-31 2 views
8

좋아, 우선 내가하고있는 일은 완전히 윤리적이며 네, 포트 스캔입니다.소켓 시간 초과 C++ Linux

포트가 열려있을 때 프로그램이 제대로 실행되지만 닫힌 소켓에 도달하면 시간 제한 절이 없어 프로그램이 매우 오랫동안 중지됩니다. 아래는 내가 스택 오버 플로우에서 이걸 발견 다음 코드

int main(){ 

    int err, net; 
    struct hostent *host; 
    struct sockaddr_in sa; 

    sa.sin_family = AF_INET; 

    sa.sin_port = htons(xxxx); 
    sa.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx"); 

    net = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    err = connect(net, (struct sockaddr *)&sa, sizeof(sa)); 

    if(err >= 0){ cout << "Port is Open"; } 
    else { cout << "Port is Closed"; } 

} 

하지만 그것은 단지 select() 명령을 사용하여 나에게 이해가되지 않습니다.

질문 connect() 함수의 시간 제한을 설정하여 오류가 발생하기까지 1 년을 기다릴 수 있습니까?

+14

필요가 없습니다에 대한 링크 - 그것은 은행 및 강탈 그것에 돈을 인출 싶어하지 않는 것이 설명 할 때마다가는 길을 묻는처럼 .. – stefanB

+1

: 멋지게 넣습니다. 그러나 돈을 인출하는 것은 아무 것도 없습니다 : D –

답변

7

가장 쉬운은 alarmconnect 신호 중단 될 수있다 (UNP 14.2 참조) 설정하는 것입니다 : select를 사용하는 것이 더 힘들어하지


signal(SIGALRM, connect_alarm); /* connect_alarm is you signal handler */ 
alarm(secs); /* secs is your timeout in seconds */ 
if (connect(fs, addr, addrlen) < 0) 
{ 
    if (errno == EINTR) /* timeout */ 
     ... 
} 
alarm(0); /* cancel alarm */ 

있지만 :)
당신은 약 raw sockets을 배울 수도 있습니다 너무.

+1

감사합니다. 그 일은 어떻게 작동하는지 알 수있는 신호와 신호를보아야 만했습니다. 감사 : D –

+0

'sigaction'은 일반적으로'signal'보다 선호되는데, 이것은 다른 유닉스에서 다른 행동을합니다. – ephemient

+0

사실이 코드는 Stevens에서 직접 인용했습니다. –

2

차단 IO를 사용하여 설정을 완료하지 못하게되면 setsockopt() 호출, 특히 SO_SNDTIMEO 플래그 (또는 OS에 따라 다른 플래그)를 조사해야합니다.

경고 :이 플래그는 신뢰할 수 있지만 이식성이 없으며 플랫폼이나 플랫폼에 따라 다르게 구현 될 수 있습니다.

이렇게하는 전통적인/최선의 방법은 select()를 사용하는 논 블로킹 방식을 사용하는 것입니다. 여러분이 소켓을 처음 접했을 때 가장 좋은 책 중 하나가 TCP/IP 일러스트 1 권 : 프로토콜입니다. 그것은 아마존에서이다 : http://www.amazon.com/TCP-Illustrated-Protocols-Addison-Wesley-Professional/dp/0201633469

+0

SO_SNDTIMEO는 connect()에서 작동하지 않습니다. – ernesto

1

RudeSocket 나에게 타임 아웃 옵션을 제공하는 내가 (윈도우 확실하지 않음) 리눅스 페도라에서 테스트 된 lib 디렉토리 파일을 볼 수있는 문제

를 해결. 아래에서 아주 간단한 예를 찾을 수 있습니다. 여기

#include <rude/socket.h> 
#include <iostream> 

using namespace std; 
using namespace rude; 

Socket soc; 
soc.setTimeout(30, 5); 

//Try connecting 
if (soc.connect("xxx.xxx.xxx.xxx", 80)){ 

    cout << "Connected to xxx.xxx.xxx.xxx on Port " << 80 << "\n"; 
} 

//connections Failed 
else{ 
    cout << "Timeout to xxx.xxx.xxx.xxx on Port " << 80 << "\n"; 
} 

soc.close(); 

은 당신이 그것을 필요로하는 이유를 설명 할 수있는 DevSite