2012-04-12 6 views
1

I Transport endpoint is not connected Fehler in UDP-Server-Programm bin immer, während ich zu Abschaltung versuchen bin der Sockel über shutdown(m_ReceiveSocketId, SHUT_RDWR); Im Anschluss an meinem Code-Schnipsel:Einsteigen UDP Socket-Programmierung in C "Transport-Endpunkt ist nicht angeschlossen" ++

bool UDPSocket::receiveMessage() 
    { 
     struct sockaddr_in serverAddr; //Information about the server 
     struct hostent *hostp; // Information about this device 

     char buffer[BUFFERSIZE]; // Buffer to store incoming message 
     int serverlen; // to store server address length 

     //Open a datagram Socket 
     if((m_ReceiveSocketId = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
     { 
      Utility_SingleTon::printLog(LOG_ERROR,"(%s %s %d) UDP Client - socket() error",__FILE__,__func__, __LINE__); 
      pthread_exit(NULL); 
      return false; 
     } 


     //Configure Server Address. 
     //set family and port 
     serverAddr.sin_family = AF_INET; 
     serverAddr.sin_port = htons(m_ListeningPort); 

     if (bind(m_ReceiveSocketId, (struct sockaddr *) &serverAddr,sizeof(struct sockaddr_in)) < 0) 
     { 
      Utility_SingleTon::printLog(LOG_ERROR,"(%s %s %d) UDP Client- Socket Bind error=%s",__FILE__,__func__, __LINE__,strerror(errno)); 
      pthread_exit(NULL); 
      return false; 
     } 

     //TODO Re-Route Mechanism. 
     if((serverAddr.sin_addr.s_addr = inet_addr(m_ServerIPStr.c_str())) == (unsigned long)INADDR_NONE) 
     { 
      /* Use the gethostbyname() function to retrieve */ 
      /* the address of the host server if the system */ 
      /* passed the host name of the server as a parameter. */ 
      /************************************************/ 
      /* get server address */ 
      hostp = gethostbyname(m_ServerIPStr.c_str()); 
      if(hostp == (struct hostent *)NULL) 
      { 
       /* h_errno is usually defined */ 
       /* in netdb.h */ 
       Utility_SingleTon::printLog(LOG_ERROR,"%s %d %s %s %d", "Host Not found", h_errno,__FILE__,__func__, __LINE__); 
       pthread_exit(NULL); 
       return false; 
      } 
      memcpy(&serverAddr.sin_addr, hostp->h_addr, sizeof(serverAddr.sin_addr)); 
     } 


     serverlen = (int)sizeof(serverAddr); 

     // Loop and listen for incoming message 
     while(m_RecevieFlag) 
     { 
      int receivedByte = 0; 
      memset(buffer, 0, BUFFERSIZE); 
      //receive data from the server 
      receivedByte = recvfrom(m_ReceiveSocketId, buffer, BUFFERSIZE, 0, (struct sockaddr *)&serverAddr, (socklen_t*)&serverlen); 
      if(receivedByte == -1) 
      { 

       Utility_SingleTon::printLog(LOG_ERROR,"[%s:%d#%s] UDP Client - receive error",__FILE__,__LINE__,__func__); 
       close(m_ReceiveSocketId); 
       pthread_exit(NULL); 
       return false; 
      } 
      else if(receivedByte > 0) 
      { 
       string rMesg; 
       rMesg.erase(); 
       for(int loop = 0; loop < receivedByte; loop++) 
        rMesg.append(1, buffer[loop]); 
       Utility_SingleTon::printLog(LOG_DEBUG,"[%s:%d#%s] received message=%d",__FILE__,__LINE__,__func__, rMesg.length()); 
       QOMManager_SingleTon::getInstance()->setReceivedMessage(rMesg); 
       raise(SIGUSR1); 
      } 

     } 

     close(m_ReceiveSocketId); 
     pthread_exit(NULL); 
     return true; 

    } 

Jede Hilfe wäre willkommen. Danke Yuvi.

+2

Sollten Sie 'serverAddr.sin_addr' nicht vor dem Aufruf von' bind' setzen? Außerdem rufst du 'shutdown' nie irgendwo an? –

+0

'shutdown' ist im Destruktor der Klasse. in Bezug auf bind glaube ich nicht .. Es funktioniert nicht, wenn ich 'bind' nach' serverAddr.sin_addr ' – Yuvi

+0

verwenden Wenn der Aufruf von' shutdown' im Destruktor ist, haben Sie den Socket in den meisten Fällen nicht schon geschlossen dann? –

Antwort

2

Sie müssen shutdown() nicht für einen UDP-Socket aufrufen. Aus der Manpage:

The shutdown() call causes all or part of a full-duplex connection on the socket 
associated with sockfd to be shut down. 

Wenn Sie shutdown() auf einem UDP-Sockets aufrufen, wird es ENOTCONN zurückkehren (Die angegebene Socket ist nicht verbunden), da UDP ein verbindungsloses Protokoll ist.

Alles, was Sie tun müssen, ist den Socket zu schließen und den Socket auf INVALID_SOCKET zu setzen. Überprüfen Sie dann in Ihrem Destruktor, ob der Socket bereits auf INVALID_SOCKET gesetzt wurde, bevor Sie ihn schließen.

+0

Wenn ich dies tue, bleibt die Ausführung des Threads bei 'recvfrom' hängen und der Thread wird nie beendet. – Yuvi

+0

@Yuvi: Wenn Sie den Socket schließen, sollte recvfrom() mit ENOTSOCK zurückkehren. Ist das nicht passiert? –

+0

Ja, aber wie man 'recvfrom' Blockierung Socket loswerden, haben Sie einen Verweis Link dafür. – Yuvi