Socket Programmierung C/C++ - recv-Funktion hängt in Server

Ich habe Probleme bei der Nutzung von recv-Funktion

Ich eine Anwendung haben, senden Sie einige Daten aus dem client, diese Daten werden von dem server empfangen & senden Antworten, die basierend auf Daten.

Die Umsetzung funktioniert gut, wenn ich weniger als ~16 Anfragen.
Aber wenn ich senden mehr als 16 Anforderung (eines nach dem anderen) vom client die Antwort sind in Ordnung, vom server bis 16 Anfrage, aber danach ist der server hängt. Ich konnte sehen, dass die Daten übermittelt werden, vom client aber nicht empfangen vom server. Ich bin mit der Funktion recv

Ist die Rezeption geschieht in einer Schleife, die beendet nur, wenn die Kündigung request wird vom client empfangen.

Server-Code:

   //Request Winsock version 2.2
   fprintf(stderr,"Performing WSAStartup\n");
   if ((retval = WSAStartup(0x202, &wsaData)) != 0)
   {
      fprintf(stderr,"FAILED with error %d\n", retval);
      WSACleanup();
      return -1;
   }
   else
   {
      printf("OK\n");
   }

   if (port == 0)
   {
      Usage(argv[0]);
   }


   /* open socket connection */
   printf("Opening socket\n");
   local.sin_family = AF_INET;
   local.sin_addr.s_addr = (!ip_address) ? INADDR_ANY:inet_addr(ip_address);
   /* Port MUST be in Network Byte Order */
   local.sin_port = htons(port);
   //TCP socket
   listen_socket = socket(AF_INET, socket_type,0);

   if (listen_socket == INVALID_SOCKET){
      fprintf(stderr,"socket() failed with error %d\n", WSAGetLastError());
      WSACleanup();
      return -1;
   }
   else
   {   
      printf("OK\n");
   }

   //bind() associates a local address and port combination with the socket just created.
   //This is most useful when the application is a
   //server that has a well-known port that clients know about in advance.
   printf("Bind address and port to socket\n");
   if (bind(listen_socket, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR)
   {
      fprintf(stderr,"bind() failed with error %d\n", WSAGetLastError());
      WSACleanup();
      return -1;
   }
   else
   {  
      printf("OK\n");
   }

   //So far, everything we did was applicable to TCP as well as UDP.
   //However, there are certain steps that do not work when the server is
   //using UDP. We cannot listen() on a UDP socket.
   if (socket_type != SOCK_DGRAM)
   {
      printf("TCP: listening on socket\n");
      if (listen(listen_socket,5) == SOCKET_ERROR)
      {
         fprintf(stderr,"listen() failed with error %d\n", WSAGetLastError());
         WSACleanup();

         return -1;
      }
      else
      {
         printf("OK\n");

      }
   }


//Perform Applcation task
//initisations

   printf("Server is listening and waiting for a connection\non port %d, protocol %s\n",port, (socket_type == SOCK_STREAM)?"TCP":"UDP");

   executeServer = 1;
   while(executeServer == 1)

   {
      fromlen =sizeof(from);
      //accept() doesn't make sense on UDP, since we do not listen()
      if (socket_type != SOCK_DGRAM)
      {
         printf("TCP: Waiting for connection (accept())\n");
         msgsock = accept(listen_socket, (struct sockaddr*)&from, &fromlen);
         if (msgsock == INVALID_SOCKET)
         {
            fprintf(stderr,"accept() error %d\n", WSAGetLastError());
            WSACleanup();
            return -1;
         }
         else
         {   
            printf("OK\n");
            printf("accepted connection from %s, port %d\n", inet_ntoa(from.sin_addr), htons(from.sin_port)) ;
         }
      }
      else
      {   
         msgsock = listen_socket;
      }

      //In the case of SOCK_STREAM, the server can do recv() and send() on
      //the accepted socket and then close it.

      //However, for SOCK_DGRAM (UDP), the server will do recvfrom() and sendto()  in a loop.

      printf("Receiving data");
      if (socket_type != SOCK_DGRAM)
      {   
         retval = recv(msgsock, Buffer, sizeof(Buffer), 0);
      }
      else
      {
         retval = recvfrom(msgsock,Buffer, sizeof(Buffer), 0, (struct sockaddr *)&from, &fromlen);
         printf("Received datagram from %s\n", inet_ntoa(from.sin_addr));

      }


      if (retval == SOCKET_ERROR)
      {
         fprintf(stderr,"recv() failed: error %d\n", WSAGetLastError());
         closesocket(msgsock);
         return -2;
      }
      else
      {
         printf("OK\n");
      }

      if (retval == 0)
      {
         printf("Client closed connection.\n");
         closesocket(msgsock);

      }
      else
      {
         printf("Received %d bytes, data \"%s\" from client\n", retval, Buffer);
      }

      printf("Processing Data\n");
      if (!stricmp(Buffer, "exit"))
      {
         wsprintf(AckBuffer,"ACK");
         executeServer = 0;
      }
      else
      {
        //Perform use task here based on recieved data

      }


      printf("Sending answer to client\n");
      if (socket_type != SOCK_DGRAM)
      {   
         retval = send(msgsock, AckBuffer, sizeof(AckBuffer), 0);
      }
      else
      {   
         retval = sendto(msgsock, AckBuffer, sizeof(AckBuffer), 0, (struct sockaddr *)&from, fromlen);
      }


      if (retval == SOCKET_ERROR)
      {
         fprintf(stderr,"send() failed: error %d\n", WSAGetLastError());
      }
      else
      {   
         printf("OK\n");
      }

      /* close TCP connection */
      if (socket_type != SOCK_DGRAM)
      {
         closesocket(msgsock);
      }


   }
   printf("terminating server\n");
   closesocket(msgsock);
   WSACleanup();

Client-Code:

 fprintf(stderr,"Performing WSAStartup");
   if ((retval = WSAStartup(0x202, &wsaData)) != 0)
   {

      fprintf(stderr,"WSAStartup() failed with error %d\n", retval);
      WSACleanup();

      return -1;
   }
   else
   {
      printf("OK\n");
   }

   if (port == 0)

   {
      Usage(argv[0]);
   }

   //Attempt to detect if we should call gethostbyname() or gethostbyaddr()
   printf("Translate hastname to address -> gethostbyaddr()\n");
   if (isalpha(server_name[0]))
   {   //server address is a name
      hp = gethostbyname(server_name);
   }
   else
   { //Convert nnn.nnn address to a usable one
      addr = inet_addr(server_name);
      hp = gethostbyaddr((char *)&addr, 4, AF_INET);
   }
   if (hp == NULL )
   {
      fprintf(stderr,"Cannot resolve address \"%s\": Error %d\n", server_name, WSAGetLastError());
      WSACleanup();
      exit(1);
   }
   else
   {
      printf("OK\n");
   }

   //Copy the resolved information into the sockaddr_in structure
   printf("Opening socket\n");
   memset(&server, 0, sizeof(server));
   memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);
   server.sin_family = hp->h_addrtype;
   server.sin_port = htons(port);

   conn_socket = socket(AF_INET, socket_type, 0); /* Open a socket */
   if (conn_socket <0 )
   {
      fprintf(stderr,"Error Opening socket: Error %d\n", WSAGetLastError());
      WSACleanup();
      return -1;
   }
   else
   {
      printf("OK\n");
   }

   //Notice that nothing in this code is specific to whether we
   //are using UDP or TCP.
   //We achieve this by using a simple trick.
   //   When connect() is called on a datagram socket, it does not
   //   actually establish the connection as a stream (TCP) socket
   //   would. Instead, TCP/IP establishes the remote half of the
   //   (LocalIPAddress, LocalPort, RemoteIP, RemotePort) mapping.
   //   This enables us to use send() and recv() on datagram sockets,
   //   instead of recvfrom() and sendto()
   printf("Client connecting to: %s.\n", hp->h_name);
   if (connect(conn_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
   {
      fprintf(stderr,"connect() failed: %d\n", WSAGetLastError());
      WSACleanup();
      return -1;
   }
   else
   {  
      printf("OK\n");
   }

   /* copy options string to buffer */     
   strcpy(Buffer,Options);
   printf("Sending Data \"%s\"\n", Buffer);
   retval = send(conn_socket, Buffer, sizeof(Buffer), 0);
   if (retval == SOCKET_ERROR)
   {
      fprintf(stderr,"send() failed: error %d.\n", WSAGetLastError());
      WSACleanup();
      return -1;
   }
   else
   {
      printf("OK\n");
   }

   printf("Receiving status from server\n");
   retval = recv(conn_socket, Buffer, sizeof(Buffer), 0);
   if (retval == SOCKET_ERROR)
   {
      fprintf(stderr,"recv() failed: error %d.\n", WSAGetLastError());
      closesocket(conn_socket);
      WSACleanup();
      return -1;
   }
   else
   {   
      printf("OK\n");
   }


   //We are not likely to see this with UDP, since there is no
   //'connection' established.
   if (retval == 0)
   {
      printf("Client: Server closed connection.\n");
      closesocket(conn_socket);
      WSACleanup();
      return -1;
   }

   printf("Received %d bytes, data \"%s\" from server.\n", retval, Buffer);
   closesocket(conn_socket);
   WSACleanup();
Kein code, keine Hilfe.
Was OS? TCP oder UDP?
Weizen: Fügen Sie den code..
Aber es ist gut zu haben, der code (im Gegensatz zu keiner), es ist nicht notwendig, um eine printf bei jedem Schritt, noch das "exception handling" - code in diesen if Zweige, die nicht speziell auf deine Frage. Schneiden Sie es auf nur die Zweige, die Sie interessieren, mit einem sanity check output-sagen "Habe hier" vor die entsprechende Zeile. Ein nützliches essay zum Thema was einen guten code-Beispiele ist hier: sscce.org

InformationsquelleAutor hemanth | 2011-09-06

Schreibe einen Kommentar