소켓을 호스트에 연결하고 파일을 다운로드하는 앱을 작성 중입니다. 응용 프로그램은 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를 사용해도 되나요?
감사합니다. 내 질문을 업데이트했습니다. – Sabya
SO_KEEPALIVE는 서버 측에 영향을 미치지 않으므로이 경우 도움이되지 않습니다. –
나는 12 시간 이상 기다렸다가 프로그램이 나오지 않았다. – Sabya