2013-08-08 3 views
1

로컬 게임 서버를 확인하기 위해 UDP 브로드 캐스트 프로그램을 만들려고하지만 수신 측에 문제가 있습니다. 살아있는 서버의 양은 항상 알 수 없으므로 중지 할 때만 종료되는 루프가 있어야합니다. 그래서 여기에 코드의이 비트에 :C++ while 루프를 벗어나는 방법 recvfrom()

while(1) // start a while loop 
     { 
    if(recvfrom(sd,buff,BUFFSZ,0,(struct sockaddr *)&peer,&psz) < 0) // recvfrom() function call 
     { 
      cout << red << "Fatal: Failed to receive data" << white << endl; 
      return; 
     } 
    else 
    { 
      cout << green << "Found Server :: " << white; 
      cout << yellow << inet_ntoa(peer.sin_addr), htons(peer.sin_port); 
      cout << endl; 
    } 
     } 

나는 Ctrl 키 + C. 내가 핸들러와 같은 (관련 질문에서) 설정을 시도했습니다 누를 때까지이에 recvfrom() 함수를 실행하려면,하지만 그들은있어 모두 나를 위해 너무 복잡하거나 시범으로 프로그램을 종료하는 간단한 기능입니다. 여기에 내 문제가있다 : 프로그램은 recvfrom에서 연결 (내 추측)을받을 때까지 중단되므로 입력을 특별히 기다릴 기회가 없다. 이처럼 잘 작동 할 수있는 이벤트를 어떻게 설정할 수 있습니까?

감사합니다.

+0

Daaksin

답변

1

CTRL-C 처리기에서 플래그를 설정하고 해당 플래그를 while 루프의 조건으로 사용하십시오.

아, 신호로 시스템 호출이 중단 될 수있는 POSIX 시스템에 없다면 소켓을 비 블로킹으로 설정하고 예를 들면 다음과 같이 사용할 수 있습니다. select (제한 시간이 짧음) 데이터를 폴링합니다.


Windows에는 이와 같은 구성에 몇 가지 문제점이 있습니다. 주요한 문제는 함수 호출이 CTRL-C 핸들러에 의해 인터럽트 될 수 없다는 것입니다. 대신 "exit loop"플래그를 확인하면서 루프에서 수신 할 항목이 있는지 폴링해야합니다. 그것은 다음과 같은 일을 할 수

:

bool ExitRecvLoop = false; 

BOOL CtrlHandler(DWORD type) 
{ 
    if (type == CTRL_C_EVENT) 
    { 
     ExitRecvLoop = true; 
     return TRUE; 
    } 

    return FALSE; // Call next handler 
} 

// ... 

SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE); 

while (!ExitRecvLoop) 
{ 
    fd_set rs; 
    FD_ZERO(&rs); 
    FD_SET(sd, &rs); 

    timeval timeout = { 0, 1000 }; // One millisecond 

    if (select(sd + 1, &rs, NULL, NULL, &timeout) < 0) 
    { 
     // Handle error 
    } 
    else 
    { 
     if (FD_ISSET(sd, &rs)) 
     { 
      // Data to receive, call `recvfrom` 
     } 
    } 
} 

여러분은 소켓 (방법에 대한 ioctlsocket 기능 참조)이 작동하려면 비 차단하기 위해 수도 있습니다.

+0

귀하의 의견에 감사드립니다. 알고 계십니까? 내가 볼 수있는 예제 나 문서는 무엇인가? – Daaksin

+0

@Daaksin 어떤 시스템 에서요? Windows 또는 POSIX (예 : Linux 또는 OSX)? –

+0

Windows주세요. – Daaksin

1

주 스레드가 사용자 입력을 기다릴 수 있도록 recvFrom() 루프를 스레드 해제하십시오. 사용자 요청이 중지되면 주 스레드에서 fd를 닫고 recvFrom()은 즉시 오류를 반환하므로 recvFrom() 스레드가 종료됩니다.

관련 문제