2014-07-01 2 views
0

recvfrom() 함수에 구현하려고합니다.recvfrom (winsock2 & udp)에 대한 제한 시간

이렇게하려면 select() 함수를 사용합니다. 나는 위대한 인터넷에서 코드를 가져 오지만 왜 사용할지 모르지만 내 프로그램이 다운됩니다. coudl 도움이되면 athread에서이 서버를 시작합니다. 여기 내가하려고 작업은 다음과 같습니다

... 
     // Setup timeval variable 
     timeval timeout; 
     timeout.tv_sec = 5; 
     timeout.tv_usec = 0; 

     // Setup fd_set structure 
     fd_set fds; 
     FD_ZERO(&fds); 
     FD_SET(id_de_la_socket, &fds); 

     // Return value: 
     // -1: error occurred 
     // 0: timed out 
     // > 0: data ready to be read 
     int retval = select(id_de_la_socket+1, &fds, NULL, NULL, &timeout); 
     if(retval == -1){ 
      printf("Error"); 
      return NULL; 
     } 
     else if(retval == 0){ 
      printf("Timeout"); 
      return NULL; 
     } 
     else{ 
      nombre_de_caractere=recvfrom(id_de_la_socket,buffer,1515,/*MSG_PARTIAL*/0,(struct sockaddr*)&information_sur_la_source,&tempo); 
... 

timeout을 구현하기 전에, 모든 것을 내 recvfrom() 블록 모드에있는, 잘 작동합니다. 그래서 문제는 제가 추가 한이 코드에서 온 것 같아요. 어쩌면 잘 이해하지 못하는 함수의 매개 변수 일 수도 있습니다.

도움 주셔서 감사합니다.

편집 : 전체 코드 :이 프로그램은 루프에서 실행, 그래서 나는 열고 잘못된 시간에 소켓을 닫는했다 : 당신의 도움에 대한

#include "serveur.h" 
#include <unistd.h> 
#include <fcntl.h> 
serveur::serveur() 
{ 
} 

StructureSupervision::T_StructureSupervision* serveur::receiveDataUDP(){ 
    WSADATA initialisation_win32; 
    int erreur; 
    int tempo; 
    int nombre_de_caractere; 
    char buffer[65535]; 
    SOCKET id_de_la_socket; 
    SOCKADDR_IN information_sur_la_source; 

    erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32); 
    if (erreur!=0) 
     printf("\nDesole, je ne peux pas initialiser Winsock du a l'erreur : %d %d",erreur,WSAGetLastError()); 
    else 
     printf("\nWSAStartup : OK"); 


    id_de_la_socket=socket(AF_INET,SOCK_DGRAM,0); 
    if (id_de_la_socket==INVALID_SOCKET) 
     printf("\nDesole, je ne peux pas creer la socket du a l'erreur : %d",WSAGetLastError()); 
    else 
     printf("\nsocket  : OK"); 


    information_sur_la_source.sin_family=AF_INET; 
    information_sur_la_source.sin_addr.s_addr = inet_addr("10.100.13.129"); // Ecoute sur toutes les IP locales 
    information_sur_la_source.sin_port=htons(4000); // Ecoute sur le port 4000 
    erreur=bind(id_de_la_socket,(struct sockaddr*)&information_sur_la_source,sizeof(information_sur_la_source)); 
    if (erreur!=0) 
     printf("\nDesole, je ne peux pas ecouter ce port : %d %d",erreur,WSAGetLastError()); 
    else 
     printf("\nbind  : OK \n"); 


    tempo=sizeof(information_sur_la_source); // Passe par une variable afin d'utiliser un pointeur 

    // Setup timeval variable 
    timeval timeout; 
    timeout.tv_sec = 5; 
    timeout.tv_usec = 0; 
    // Setup fd_set structure 
    fd_set fds; 
    FD_ZERO(&fds); 
    FD_SET(id_de_la_socket, &fds); 
    // Return value: 
    // -1: error occurred 
    // 0: timed out 
    // > 0: data ready to be read 
    ULONG NonBlock = 1; ioctlsocket(id_de_la_socket, FIONBIO, &NonBlock); 
    int retval = select(id_de_la_socket+1, &fds, NULL, NULL, &timeout); 
    if(retval == -1){ 
     printf("Error"); 
     return NULL; 
    } 
    else if(retval == 0){ 
     printf("Timeout"); 
     return NULL; 
    } 
    else{ 
    nombre_de_caractere=recvfrom(id_de_la_socket,buffer,1515,/*MSG_PARTIAL*/0,(struct sockaddr*)&information_sur_la_source,&tempo); 
    buffer[nombre_de_caractere]=0; // Permet de fermer le tableau apr�s le contenu des data, car la fonction recvfrom ne le fait pas 
    //printf("\nVoici les donnees : %s",buffer); 
    StructureSupervision::T_StructureSupervision *structureReception = (StructureSupervision::T_StructureSupervision *) buffer; 
    std::cout << "Voici le numero de Statut Ground Flight : " << structureReception->SystemData._statutGroundFlight; 


    erreur=closesocket(id_de_la_socket); 
    if (erreur!=0) 
     printf("\nDesole, je ne peux pas liberer la socket du a l'erreur : %d %d",erreur,WSAGetLastError()); 
    else 
     printf("\nclosesocket : OK"); 

    // ******************************************************** 
    // Quitte proprement le winsock ouvert avec la commande WSAStartup 
    // ******************************************************** 
    erreur=WSACleanup(); // A appeler autant de fois qu'il a �t� ouvert. 
    if (erreur!=0) 
     printf("\nDesole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError()); 
    else 
     printf("\nWSACleanup : OK"); 

    return structureReception; 
    } 
} 
+0

'select '가 -1을 반환하는지 확인하지 않습니다. 남자 예제에서와 같이'int retval = select (...);'과 같은 것을 추가하고'retval == -1'이라면 errno를 보아라 : http://linux.die.net/man/2/select – Holt

+0

완료되었지만 아무것도 변경하지 않은 경우 내 게시물을 업데이트합니다. –

+0

소켓에 비 차단 모드를 설정 했습니까? – Holt

답변

0

덕분에 문제가 있었다.