2013-05-02 1 views
1

각 클라이언트 응용 프로그램과 함께 소켓을 열어 놓은 스레드가 여러 개 있습니다. 이들 스레드 각각은 주 스레드로부터 명령을 수신하여 명령을 클라이언트에 전송합니다 (명령은 테스트 실행, 테스트 중지, 세션 종료, 종료 ...). 이 쓰레드는 일반적인 쓰래드 다. 클라이언트 당 소켓을 가지고 있고, 메인 쓰레드가 요청하면 커맨드를 보냅니다.SO_KEEPALIVE : 연결 유실 또는 종료 감지

클라이언트가 종료되거나 충돌하거나 네트워크가 손상 될 수 있습니다.

저는 클라이언트마다 TCP 세션이 끝났음을 알 수있는 방법을 찾으려고했습니다. 내가 찾은 두 가지 해결책이 여기서 적절하게 보입니다.

1) 자체 하트 비트 시스템 구현 2) setsockopt를 사용하여 keepAlive를 사용하십시오.

2) 구현하기가 더 빠르다고 들었지만 한 가지 확실하지 않습니다. 연결이 끊어지면 SO_KEEPALIVE가 SIGPIPE을 생성합니까? 나는 그것이 사실이어야하지만 SIGPIPE를받은 적이 없다는 것을 알았다.) (

void test(int n) { 
    printf("Socket broken: %d\n", n); 
} 

시험 :

void setKeepAlive(int sockfd) { 
    int optval; 

    optval = 1; 
    setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)); 
    optval = 1; 
    setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, &optval, sizeof(optval)); 
    optval = 1; 
    setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &optval, sizeof(optval)); 
    optval = 1; 
    setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, &optval, sizeof(optval)); 
} 

다음과 같이 연결이 받아 내 코드 :

for (mNumberConnectedClients = 0; mNumberConnectedClients < maxConnections; ++mNumberConnectedClients) { 
    clientSocket = accept(sockfd, (struct sockaddr *) &client_addr, &clientLength); 

    // set KeepAlive on socket 
    setKeepAlive(clientSocket); 

    pthread_create(&mThread_pool[mNumberConnectedClients], NULL, controlClient, (void*) &clientSocket); 
} 

signal(SIGPIPE, test); 
.... 

그리고 테스트 기능을

이 내 코드는 모습입니다 결코 방아쇠를 당하지 않는다. 제발 이해가 잘못 되었나요? 나는 SIGPIPE가 만들어 지는지 확신 할 수 없다. 고마워.

답변

1

연결 유지가 실패한 경우 연결은 OS에 의해 무효화되고 해당 소켓에 대한 후속 읽기/쓰기 작업은 해당 오류 코드와 함께 실패합니다. 소켓을 닫을 수 있도록 읽기/쓰기 코드가 오류를 처리하는지 확인해야합니다 (아직 수행하지 않은 경우).

+0

감사합니다. 그래서 인터럽트에 의지 할 수 없으므로, 모든 것을 자주 작성해야합니다. 나는 그때 내 자신의 심장 박동을 사용할 것이다. 감사! – user1777907