呃, 我认为我的代码是正确的,但它不起作用:(
要在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。
请问有人可以帮助我吗?
最佳答案
您的代码在超时后尝试使用套接字。这不是一个好主意,因为套接字仍然处于失败的阻塞操作中间的某个位置,并且无法开始新的操作。无法展开之前已完成的操作部分并将套接字放回到操作开始之前的位置。
一旦阻塞套接字操作超时,您所能做的就是安全地关闭套接字。不支持撤消部分完成的操作并使套接字保持任何正常状态。
If a send or receive operation times out on a socket, the socket state is indeterminate, and should not be used[.] -- MSDN
SO_RCVTIMEO 套接字选项绝不应该在设计用于套接字的代码中使用。这是为了防止代码中的无限等待而设计的,这些代码本来就不是为使用套接字而设计的。这些不是您要寻找的机器人。
关于c++ - 在 Windows 上设置从套接字接收的超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39375481/