2011-08-17 3 views
3

원래 문제에 대한 해결책을 찾지 못했기 때문에 약간의 해결 방법을 시도했습니다. 나는 단순히 내 TCP 소켓의 connect() 호출에 대한 타임 아웃을 설정하려하고있다.Alarm()으로 연결 시간 제한

  1. 나는 connect()을 블로킹하고 싶지만 보통 75 초가지기 전까지는 내 자신을 정의하고 싶습니다.
  2. 나는 이미 타임 아웃을 위해 일했던 select()을 시도했지만 연결을 얻을 수 없었다. (이것은 초기 문제인 here으로 묘사되었다). 다만 차단 connect() 전화를 할 수 있지만,이 같은 알람을 중단 : 이것은이다

    signal(SIGALRM, connect_alarm); 
        int secs = 5; 
        alarm(secs); 
        if (connect(m_Socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) 
        { 
         if (errno == EINTR) 
         { 
          debug_printf("Timeout"); 
          m_connectionStatus = STATUS_CLOSED; 
          return ERR_TIMEOUT; 
         } 
         else 
         { 
          debug_printf("Other Err"); 
          m_connectionStatus = STATUS_CLOSED; 
          return ERR_NET_SOCKET; 
         } 
        } 
    

    static void connect_alarm(int signo) 
    { 
        debug_printf("SignalHandler"); 
        return; 
    } 
    

그래서 지금은 그것을 다루는 또 다른 방법을 찾아 솔루션 난 stackoverflow에 스레드 here에서 인터넷에서 발견. 이 코드를 사용하면 프로그램이 타이머를 시작한 다음 connect() 호출로갑니다. 5 초 후 (콘솔에서 볼 수 있듯이) 신호 처리기가 실행되었지만 그 후 프로그램은 여전히 ​​connect() 함수 내에 75 초 동안 남아 있습니다. 사실 모든 설명은 connect_alarm()connect() 기능을 중단해야한다고 말하지만 내 경우에는 그렇지 않습니다. 내 문제에 대해 원하는 결과를 얻을 수있는 방법이 있습니까?

+0

1 주일 후에 문제가 해결되었습니다 ... – Nirav

+0

sigaction으로 구현 했습니까? – ernesto

답변

2

signal은 많이 지정되지 않은 인터페이스이므로 새 코드에서는 피해야합니다. Linux의 일부 버전에서는 기본적으로 SA_RESTART을 제공한다는 것을 의미하는 "BSD 의미"를 제공한다고 생각합니다.

대신 sigaction을 사용하고 SA_RESTART을 지정하지 않으면 잘 읽어야합니다.

...

음, 일반 취약성과 피할 수없는 경쟁 조건을 제외하고, 그입니다. connect의 경우 을 이 아니라 신호로 반환합니다. 시스템이 과부하 상태 인 경우 alarm 호출과 connect 호출 사이에 5 초 이상 걸릴 수 있습니다.이 경우 신호를 놓치고 connect에 영원히 차단됩니다.

connectselect과 함께 비 블로킹 소켓을 사용했던 이전의 시도는 훨씬 더 좋은 아이디어였습니다. 나는 그것을 디버깅하는 것이 좋습니다.

+0

sigaction이 connect()에서 작동하지 않습니다. openSuSe 12 64 비트. SA 플래그를 모두 지웠습니다. – ernesto

1

(신호 처리 및 시스템 호출 중단의 고통이 적음)을 설정하는 것이 상대적으로 쉽지만, TCP 연결 시도를 시간 초과하는 더 효율적인 방법은 non-blocking connect이며 여러 연결을 시작하고 대기 모두 성공과 실패를 한 번에 하나씩 처리합니다.