gpt4 book ai didi

macos - 如果MacBook sleep 时间超过10分钟,则套接字 “read”挂起

转载 作者:行者123 更新时间:2023-12-03 12:06:57 24 4
gpt4 key购买 nike

我正在编写一个应用程序,其中套接字将连接到主机并下载文件。
该应用程序在Mac中运行。

现在,在下载应用程序时,如果我将MacBook置于 sleep 模式超过10分钟,则计算机唤醒时,应用程序挂起的时间有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吗?

最佳答案

TCP/IP连接无法在 sleep 模式下生存。 SO_KEEPALIVE在这种情况下无济于事,因为它对服务器端没有影响。只需等待两分钟,读取将超时。超时后,您可以再次连接。

而且,该sleep(1)是不必要的。数据可用后,服务器将立即响应。如果没有立即获取,您将在服务器上分配连接的时间超过了您需要的时间。

关于macos - 如果MacBook sleep 时间超过10分钟,则套接字 “read”挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1672381/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com