2016-10-03 13 views
0

다음과 같은 동작을 구현해야합니다. 서버가 시작될 때 브로드 캐스트를 사용하는 기존 서버를 확인해야합니다. 그런 다음 대답을 기다립니다.C++ recvfrom timeout

그러나 대기 시간 제한을 설정하는 방법은 무엇입니까?

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); 
+5

'select (2)'를 사용하거나 nonblocking으로 설정하고'epoll (2)'을 사용하십시오. –

답변

1

setsockopt()SO_RCVTIMEO으로 읽기 제한 시간을 설정하고 시간 제한이 발생할 경우 발생하는 EAGAIN/EWOULDBLOCK을 처리하십시오.

+0

SO_RCVTIMEO는 recv()에서만 사용 가능하지 않습니까? https://msdn.microsoft.com/en-us/library/windows/desktop/ms740476(v=vs.85).aspx – Evgeniy175

+0

잘 작동합니다. – Evgeniy175

+0

그것은 모든'recv ()'패밀리와 Winsock 시스템을 제외하고는'read()'를 위해서 사용된다. – EJP

0

일반적인 방법은 filedescriptors 세트에서 이벤트를 기다리는 select() 또는 poll()을 사용하는 것입니다. 이러한 함수를 사용하여 시간 초과를 지정할 수도 있습니다. 귀하의 경우에는, 상기 recvfrom() 호출하기 전에 다음을 추가합니다

struct pollfd pfd = {.fd = s, .events = POLLIN}; 
poll(&pfd, 1, 1000); 

이 1000 밀리 초를 기다립니다. 패킷이 소켓 s에 도착하거나 1 초 후 중 빠른 날짜가되면 패킷이 종료됩니다. poll()의 반환 값을 확인하여 패킷 때문에 또는 시간 초과로 인해 반환되었는지 확인할 수 있습니다.

+0

유감스럽게도 지정된 초기화 프로그램 목록에서 C와 C++의 구문 차이 중 하나를 건너 뜁니다. – user4581301

+0

@ user4581301 : C99 및 C++ 11 모두에서 유효합니다. –

+0

C++ 14로 미끄러 져 들어가는 것에 대한 이야기가있었습니다. 그러나 C++ 17 초안의 경우에는 [dcl.init.aggr]에서 아직 볼 수 없습니다. GCC는 이것을 확장으로 제공하는 것으로 보입니다. – user4581301