Partage
  • Partager sur Facebook
  • Partager sur Twitter

nombre de connexion au serveur TCP limitée

Sujet résolu
    3 février 2019 à 1:10:55

    Bonjour,

    j'ai commencé a développée pour un programme une classe serveur, elle fonctionne correctement mais en fessent des tests j'ai trouvée un problème la fonctionne "accept" ce bloc au bout d'environ  22 000 connexions.

    Pour le programme ça ne bloc pas, mais j'aimerais ne pas tournée le dos a cette erreur.

    main.cpp:

    int main(int argc, char** argv) {
        NetworkLibrary::ServeurTCP::ServeurTCPBasic serveur;
        
        serveur.setPort(9874);
        
        unsigned int i = 0;
        
        for(;;){
            i++;
            try{
                std::shared_ptr<NetworkLibrary::Information::IInformationClient> client = serveur.newClient();
                std::string data = serveur.recvData(client);
                serveur.recvData(client);
            }catch (const NetworkLibrary::ExceptionServerTCPBasic& e){
                if(e != NetworkLibrary::ExceptionServerTCPBasic(NetworkLibrary::ErreurServerTCPBasic::ERROR_CLOSE_SOCKET)){
                    std::cout <<"erreur : "<<e.what()<<std::endl;
                    return e.get().first;
                }
            }
            std::cout <<i<<std::endl;
        }
        
        return 0;
    }


    ServeurTCPBasic.cpp :

    #include "ServeurTCPBasic.hpp"
    #include "Exception/ExceptionServerTCPBasic.hpp"
    
    NetworkLibrary::ServeurTCP::ServeurTCPBasic::ServeurTCPBasic() {
    }
    
    void NetworkLibrary::ServeurTCP::ServeurTCPBasic::setPort(unsigned int port) {
            #if defined (WIN32)
            WSADATA WSAData;
            if(WSAStartup(MAKEWORD(2,2), &WSAData))
                throw NetworkLibrary::ExceptionServerTCPBasic(NetworkLibrary::ErreurServerTCPBasic::ERROR_WINDOWS_WSADATA);
        #endif
        sock = socket(AF_INET, SOCK_STREAM, 0);
        
        if(sock == INVALID_SOCKET)
            throw NetworkLibrary::ExceptionServerTCPBasic(NetworkLibrary::ErreurServerTCPBasic::ERROR_CREATE_SOCKET);
            
        sin.sin_addr.s_addr = htonl(INADDR_ANY);
        sin.sin_family = AF_INET; 
        sin.sin_port = htons(port);
        
        if( bind(sock, (SOCKADDR*)&sin, sizeof(sin)) == SOCKET_ERROR)
            throw NetworkLibrary::ExceptionServerTCPBasic(NetworkLibrary::ErreurServerTCPBasic::ERROR_BIND_SOCKET);
        
        if(listen(sock, SOMAXCONN) == SOCKET_ERROR)
            throw NetworkLibrary::ExceptionServerTCPBasic(NetworkLibrary::ErreurServerTCPBasic::ERROR_LISTEN_SOCKET);
    }
    
    void NetworkLibrary::ServeurTCP::ServeurTCPBasic::start() {
    }
    
    std::shared_ptr<NetworkLibrary::Information::IInformationClient> NetworkLibrary::ServeurTCP::ServeurTCPBasic::newClient() {
        return newClientBasic();
    }
    
    void NetworkLibrary::ServeurTCP::ServeurTCPBasic::sendData(std::shared_ptr<NetworkLibrary::Information::IInformationClient> information, std::string data) {
        sendDataBasic(std::static_pointer_cast<NetworkLibrary::Information::InformationClientBasic>(information), data);
    }
    
    std::string NetworkLibrary::ServeurTCP::ServeurTCPBasic::recvData(std::shared_ptr<NetworkLibrary::Information::IInformationClient> information) {
        return recvDataBasic(std::static_pointer_cast<NetworkLibrary::Information::InformationClientBasic>(information));
    }
    #include <iostream>
    std::shared_ptr<NetworkLibrary::Information::InformationClientBasic> NetworkLibrary::ServeurTCP::ServeurTCPBasic::newClientBasic() {
        std::shared_ptr<NetworkLibrary::Information::InformationClientBasic> data = std::shared_ptr<NetworkLibrary::Information::InformationClientBasic>(new NetworkLibrary::Information::InformationClientBasic()) ;
        
        data->setSocklen(sizeof(data->getSockaddr()));
        data->setSocket( accept(sock, reinterpret_cast<SOCKADDR*>(&data->getSockaddr()), &data->getSocklen()));
        if (data->getSocket() == INVALID_SOCKET)
            throw NetworkLibrary::ExceptionServerTCPBasic(NetworkLibrary::ErreurServerTCPBasic::ERROR_ACCEPT_NEW_CLIENT);
        
        return data;
        
    }
    
    void NetworkLibrary::ServeurTCP::ServeurTCPBasic::sendDataBasic(std::shared_ptr<NetworkLibrary::Information::InformationClientBasic> information, std::string data) {
        int ret = send(information->getSocket(), data.c_str(), SIZE_MAX_TCP, 0);
        if (ret == 0 || ret == SOCKET_ERROR){
            closesocket(information->getSocket());
            /*
            #if defined (WIN32)
                WSACleanup();
            #endif
             */
            throw NetworkLibrary::ExceptionServerTCPBasic(NetworkLibrary::ErreurServerTCPBasic::ERROR_CLOSE_SOCKET);
        }
            
    }
    
    std::string NetworkLibrary::ServeurTCP::ServeurTCPBasic::recvDataBasic(std::shared_ptr<NetworkLibrary::Information::InformationClientBasic> information) {    
        char buffer[SIZE_MAX_TCP+1] = { 0 };
        
        int ret = recv(information->getSocket(), buffer, SIZE_MAX_TCP, 0);
        if (ret == 0 || ret == SOCKET_ERROR){
            closesocket(information->getSocket());
            closesocket(information->getSocklen());
            /*
            #if defined (WIN32)
                WSACleanup();
            #endif
             */
            throw NetworkLibrary::ExceptionServerTCPBasic(NetworkLibrary::ErreurServerTCPBasic::ERROR_CLOSE_SOCKET);
        }
            
        
        return std::string(buffer);
    }
    
    NetworkLibrary::ServeurTCP::ServeurTCPBasic::~ServeurTCPBasic() {
    }
    
    


    merci d'avance pour votre aide .

    • Partager sur Facebook
    • Partager sur Twitter
      3 février 2019 à 19:43:59

      Salut,

      22 000 connexions ! C'est quand même assez énorme non ? 

      Pour quelle application est ce que ça va te poser soucis ?


      Si tu me parles des MMORPG a millions de joueurs, ce qui est fait, c'est que dès qu'un joueur se connecte sur l'ordinateur "portail", il distribue les clients qui arrivent  à tout un pool d'ordinateurs. Ainsi l'ordinateur qui reçoit dispatche les clients à plein d'autres ordis. 

      • Partager sur Facebook
      • Partager sur Twitter

      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        4 février 2019 à 1:43:23

        Désolé mais je me suis mal exprimée .

        Ce n'est pas 22 000 connexions simultanées mais 22 000 connexion/déconnexion .

        Pour ce test il n'y a une seule connexion simultanée.

        code client :

        void testSocket(){
            NetworkLibrary::ClientTCP::ClientTCPBasic client;
            client.connectToServer("127.0.0.1",9874);
            client.sendData("data:test");
            std::string reponce = client.recvData();
            std::cout <<"reponce : "<<reponce<<std::endl;
            
        }
        
        int main(int argc, char** argv) {
            unsigned int connexion = 1;
            
            for(;;){
                testSocket();
                connexion++;
                std::cout <<connexion<<std::endl;
                NetworkLibrary::Time::sleepMilliSeconds(50);
            }
            
            return 0;
        }



        • Partager sur Facebook
        • Partager sur Twitter
          4 février 2019 à 9:49:23

          Salut,

          Alors a mon avis, il faut déconnecter. Tu ne dois pas déconnecter proprement. 

          • Partager sur Facebook
          • Partager sur Twitter

          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

            4 février 2019 à 16:04:51

            Si vous ne fermez pas correctement les connexions, l'OS garde des ressources sur cette connexion.

            L'OS limite les ressources utilisées par une socket d'écoute pour limiter les risques d'attaque par création de demi-connexion, par exemple.

            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              4 février 2019 à 22:09:22

              J'ai oublié de mettre la fonction "close()" dans le destructeur. (il faut que j'arrête de travailler a 1 h du matin :)).

              J'ai aussi fait un test, si je connecte/déconnecte environ 16 370 clients en environ 50 s le serveur refusera tout connexion pendant environ 90 s puis recommencera.

              Je n'est pas testée sur Linux mais je suppose que c'est différent si une personne sait ?

              Un grand merci a Fvirtman et a bacelar pour votre aide.

              À un autre jour,a autre heur.

              • Partager sur Facebook
              • Partager sur Twitter
                5 février 2019 à 11:22:42

                C'est fonction du paramétrage de l'OS donc aussi de l'OS en lui-même.
                • Partager sur Facebook
                • Partager sur Twitter
                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                nombre de connexion au serveur TCP limitée

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown