2009-11-04 2 views
1

소켓을 호스트에 연결하고 파일을 다운로드하는 앱을 작성 중입니다. 응용 프로그램은 Mac에서 실행됩니다.MacBook이 10 분 이상 잠자기하면 "read"소켓이 붙습니다.

MacBook을 절전 모드로 전환하면 컴퓨터가 깨어날 때 응용 프로그램이 중단되는 시간이 60 % 이상입니다.

스택 추적은 "읽기"호출에서 중단되었음을 보여줍니다. 나는 샘플 프로그램으로 이것을 재현 할 수있다. 아래에서는 샘플 프로그램 코드와 스택 위치를 붙여 넣었습니다. 이 교수형을 해결하는 방법?

또한 이것은 몇 분 안에 TCP/IP 대기 상태가되는 것이 아닙니다. 나는 12 시간 이상 기다렸다. 나왔다.

스택 추적 : -

Call graph: 
    2466 Thread_2507 
     2466 start 
     2466 read$UNIX2003 
      2466 read$UNIX2003 

프로그램 : -

#include <stdio.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/socket.h> 
#include <unistd.h> 

#define buflen 131072 
unsigned int portno = 80; 
char hostname[] = "192.168.1.9"; 

int main() 
{ 
    int sd = socket(AF_INET, SOCK_STREAM, 0); /* init socket descriptor */  
    struct sockaddr_in sin; 
    struct hostent *host = gethostbyname(hostname); 
    char buf[buflen]; 
    int len; 
    int ret; 
    FILE *fp; 
    int i; 

    if(sd == -1){ 
     printf("Could not create client socket\n"); 
     return 1; 
    } 

    /*set keep alive*/ 
    int optval = 1; 
int optlen = sizeof(optval); 
    ret = setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); 
    if(ret != 0){ 
     printf("could not set socket option.\n"); 
     return 1; 
    } 

    /*** PLACE DATA IN sockaddr_in struct ***/ 
    memcpy(&sin.sin_addr.s_addr, host->h_addr, host->h_length); 
    sin.sin_family = AF_INET; 
    sin.sin_port = htons(portno); 

    /*** CONNECT SOCKET TO THE SERVICE DESCRIBED BY sockaddr_in struct ***/ 
    if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 
     perror("connecting"); 
     return 1; 
    } 

    char *str = "GET /general-log.exe/HTTP/1.0\n\n"; 

    ret = write(sd, str, strlen(str)); 
    if(ret < 0){ 
     printf("error while writing\n"); 
     return 1; 
    } 


    fp = fopen("downloaded.file", "wb+"); 
    if(fp == NULL){ 
     printf("not able to open the file.\n"); 
     return 1; 
    } 

    i = 0; 
    while ((len = read(sd, buf, buflen)) > 0) {   
     printf("%d\t%d\n", i++, len); 
     fwrite(buf, len, 1, fp); //we should check for return 
    } 
    if(len < 0){ 
     printf("Error while reading\n"); 
    } 

    fclose(fp); 
    close(sd); 
    return 0; 
} 

업데이트 분명히 SO_RCVTIMEOUT이 문제를 해결한다.

struct timeval tv; 
tv.tv_sec=10; 
tv.tv_usec=0; 
setsockopt (m_sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof (tv)); 

SO_RCVTIMEO를 사용해도 되나요?

답변

0

차단 소켓을 사용하여 해결할 수 없습니다. IMAP 라이브러리를 비 블로킹 소켓으로 변경해야했습니다.

1

TCP/IP 연결은 절전 모드에서도 작동하지 않습니다. SO_KEEPALIVE은 서버 측에 영향을 미치지 않으므로이 경우 도움이되지 않습니다. 2 분 정도 기다리면 읽기 시간이 초과됩니다. 시간 초과 후 다시 연결할 수 있습니다.

그리고 sleep(1)은 필요하지 않습니다. 서버는 데이터가 사용 가능한 즉시 응답합니다. 가져 오지 않는 경우 즉시 필요에 따라 서버에 연결을 할당합니다.

+0

감사합니다. 내 질문을 업데이트했습니다. – Sabya

+0

SO_KEEPALIVE는 서버 측에 영향을 미치지 않으므로이 경우 도움이되지 않습니다. –

+0

나는 12 시간 이상 기다렸다가 프로그램이 나오지 않았다. – Sabya

관련 문제