Question

Je suis en train d'écrire un La BOUE serveur à des fins personnelles à des fins de formation et j'ai heureusement réussi à envelopper le support des choses dans un couple de classes et tout semble fonctionner correctement;le serveur écoute et accepte les connexions et pour l'instant, prend le texte à partir du client et l'envoie à l'arrière droit.

Le truc c'est que je ne suis pas tout à fait sûr de quoi faire avec un appel à accept() qui renvoie autre chose que WSAEWOULDBLOCK ou un socket valide.Dois-je simplement réinitialiser le nouveau socket 0 et retour, avec peut-être un message d'erreur en disant quelque chose de mauvais s'est passé?C'est ce que je suis en train de faire maintenant, avec l'ajout d', si cela se passe 20 fois, je vais arrêter le serveur.

void MUDControlSocket::Poll()
{
   // create a new connection here
   timeval timeout;

   FD_ZERO(&ReadSet);
   FD_ZERO(&WriteSet);
   FD_ZERO(&ExceptionSet);

   TopSocket = GetSocket();
   NewSocket = 0;
   FD_SET( GetSocket(), &ReadSet );

   if( SocketList.size() > 0 )
   {
      for( sockIter iter = SocketList.begin(); iter != SocketList.end(); ++iter )
      {
         FD_SET((*iter)->GetSocket(), &ReadSet);
         FD_SET((*iter)->GetSocket(), &WriteSet);
         FD_SET((*iter)->GetSocket(), &ExceptionSet);
         TopSocket = (*iter)->GetSocket();
      }
   }

   if( select( TopSocket+1, &ReadSet, &WriteSet, &ExceptionSet, &timeout ) == SOCKET_ERROR )
   {
      cout << "Error on select() call: " << SocketErrorType(WSAGetLastError()) << endl;

      delete this;
      exit(EXIT_FAILURE);
   }

   // as long as everything is working correctly, this if block should always be entered UNLESS a new connection is accepted
   if( (NewSocket = accept(GetSocket(), NULL, NULL) ) == INVALID_SOCKET )
   {
      if( WSAGetLastError() == WSAEWOULDBLOCK ) // it's not an actual problem. just nothing to connect to yet
         return;
      NewSocket = 0;
      static int count = 0;
      cout << "Error on accepting new connection: " << SocketErrorType(WSAGetLastError()) << endl;
      if( ++count >= 20 )
         done = true;
      return;
   }

   SocketList.push_back(new MUDSocket(NewSocket)); // only happens if accept DOES NOT return a value of INVALID_SOCKET i.e. a new connection was accepted
   TopSocket = NewSocket;
   NewSocket = 0;
}

TopSocket et NewSocket sont de type SOCKET et a déclaré à la portée de fichier.SocketList est un std::liste des MUDSocket* et MUDControlSocket est dérivé de MUDSocket comme un singleton.

Laissez-moi savoir si vous avez besoin de plus d'info et merci pour toute aide.

Était-ce utile?

La solution

D'abord:ne réglez pas le socket à 0:c'est une bonne fd pour les sockets sur certains systèmes *NIX, et une mauvaise habitude à prendre.Supposons le seul socket non valide fd est -1.Faire quelque chose d'autre vous donne un vrai bugs dans le réel logiciel de la suite (faites-moi confiance:Je parle de l'expérience de débogage de code utilisé 0 non valide prise fd).

Autre que cela, je dirais juste soulever une exception: accept ne devrait pas échouer, à moins que vous manquez de ressources, qui devraient être à la fois exceptionnel et une erreur.C++ dispose d'un mécanisme pour le traitement de telles choses, et que des exceptions.

BTW: delete this est presque toujours une très mauvaise idée, de sortir dans le milieu de votre code peut rendre difficile à déboguer (lever une exception en place) et l'appelant de ne le sortir en cas de besoin) et au lieu d'essayer d'accepter une prise avec accept vous pouvez utiliser select pour vous dire qu'il n'y a rien à accepter - et déplacez le cas de la manipulation de la fonction à sélectionner uniquement là.Vous pourriez aller un peu plus loin et de mettre en œuvre une spécialisée modèle observateur (comme je l'ai fait sur mon podcast il y a un mois) à la pratique n'est pas seulement votre code de mise en réseau, mais vos modèles de conception ainsi.Ce serait aussi aider à rendre votre code plus portable, et ré-utilisables plus tard.

HTH

Autres conseils

Renvoie l'erreur et laissez le code d'appel qui le traite de manière appropriée.

Certaines des autres erreurs possible d'accepter sont que la mémoire est faible, le nombre de connexions est épuisé, etc., etc.

Peut-être peut-être peut-être être géré en fermant des connexions inutilisées ou oubliées, ou simplement abandonner et jeter une exception.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top