问题
I need to implement following behavior: when server starts, it should check for existing servers using broadcast. Then it waits for answer.
But, how to set any timeout for waiting?
int optval = 1;
char buff[BUFF_SIZE];
SOCKADDR_IN addr;
int length = sizeof(addr);
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&optval, sizeof(optval)) == SOCKET_ERROR) throw(errors::SETSOCKOPT);
addr->sin_family = AF_INET;
addr->sin_port = htons(this->serverPort);
addr->sin_addr.s_addr = INADDR_ANY;
sendto(s, this->serverName.c_str(), this->serverName.length() + 1, NULL, (SOCKADDR*)&addr, sizeof(addr));
memset(&addr, NULL, sizeof(addr));
recvfrom(s, buff, BUFF_SIZE, NULL, (SOCKADDR*)&addr, &length);
回答1:
Set a read timeout with setsockopt()
and SO_RCVTIMEO
, and handle EAGAIN/EWOULDBLOCK
which occurs if the timeout is triggered.
回答2:
The common way is to use select()
or poll()
to wait for an event on a set of filedescriptors. These functions also allow you to specify a timeout. In your case, add the following before the recvfrom()
call:
struct pollfd pfd = {.fd = s, .events = POLLIN};
poll(&pfd, 1, 1000);
This will wait 1000 milliseconds. This will exit when a packet has arrived on socket s
, or after 1 second, whichever comes first. You can check the return value of poll()
to see if it returned because of a packet or because of a timeout.
来源:https://stackoverflow.com/questions/39840877/c-recvfrom-timeout