在Windows上设置来自套接字的recv超时

Set a timeout for recv from socket on Windows

本文关键字:套接字 recv 超时 Windows 设置      更新时间:2023-10-16

Ih,我认为我的代码是正确的,但它不起作用:(

要在windows上设置recv功能的超时,我知道我必须使用以下代码:

                    DWORD timeout = 2000;
                 if (setsockopt(listenSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(DWORD)))
                 { perror("setsockopt");
                return -1;
                 }

但它不起作用。

我的服务器代码是:

    SOCKET listenSocket;
SOCKET remoteSocket= INVALID_SOCKET;
SOCKADDR_IN Server_addr;
SOCKADDR_IN Client_addr;
int sin_size;
short port;
int wsastartup;
int ls_result;
WORD wVersionRequested = 0x0202;
WSADATA wsaData;
wsastartup = WSAStartup(wVersionRequested, &wsaData);
if (wsastartup != NO_ERROR) cout << "Errore WSAStartup()" << endl;
listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
port = 4000;
Server_addr.sin_family = AF_INET;
Server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
Server_addr.sin_port = htons(port);
if (bind(listenSocket,(LPSOCKADDR) &Server_addr,sizeof(struct sockaddr)) < 0) {
    cout << "Server: error bind." << endl;
closesocket(listenSocket);
return -1;
}
ls_result = listen(listenSocket, SOMAXCONN);
sin_size = sizeof(struct sockaddr_in);
remoteSocket = accept(listenSocket, (struct sockaddr *) &Client_addr, &sin_size);
// SET THE TIME OUT
DWORD timeout = 300;
if (setsockopt(remoteSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(DWORD)))
{ perror("setsockopt");
    return -1;
}
int i=0;
while (i<50){
    t_start = clock();
    // when client receives the send below it wait 3 seconds and then trasmits the answer
    send(remoteSocket, "code of start transmission", sizeof("code of start transmission"), 0);
    recv_size=recv(remoteSocket, messaggio, sizeof(messaggio), 0);
    printf("time for read=  %f second n", ((double)(end - t_start)) / CLOCKS_PER_SEC);
    i=i+1;
}

客户端收到来自服务器的消息"开始传输代码"时,等待3秒,然后切换到服务器。我期望读取时间为300毫秒,并且recv_size<0,而不是recv_size<0,但读取时间大约为1.5秒(服务器等待客户端的消息(。我不明白为什么。

我在windows上,使用eclipse和mingw-w64。

有人能帮我吗??

您的代码在套接字超时后尝试使用它。这不是一个好主意,因为套接字仍然处于失败的阻塞操作的中间位置,并且没有启动新操作的形状。无法展开之前已完成的操作部分,也无法将套接字放回操作开始前的位置。

一旦阻塞套接字操作超时,您所能安全地做的就是关闭套接字。不支持撤消部分完成的操作并使套接字处于任何正常状态。

如果套接字上的发送或接收操作超时,则套接字状态是不确定的,不应使用[.]-MSDN

SO_RCVTIMEO套接字选项不应用于设计用于套接字的代码中。这是为了防止代码中的无限等待,而这些代码并不是为本机使用套接字而设计的。这些不是你要找的机器人。

要在windows上设置recv功能的超时,我知道我必须使用以下代码:

             DWORD timeout = 2000;
             if (setsockopt(listenSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(DWORD)))
             { perror("setsockopt");
            return -1;
             }

没有。它应该是int,而不是DWORD,但主要问题是您在这里设置了accept()超时,因为这是侦听套接字。您需要将其设置在已接受的套接字上。