Partage
  • Partager sur Facebook
  • Partager sur Twitter

Diffuser un programme utilisant le résau

    5 juin 2019 à 17:10:40

    Bonjour a tous, suite a un exercice du cours de Matteo, j'ai créer un programme qui sert à échanger des messages en ligne.

    Le programme fonctionne bien, du moins en interne, et voulant voir s'il fonctionnait sur un autre ordinateur, je l'ai compiler en release, ai ajouter touts les bibliothèque que différents tutos indiquaient, puis ai transmis l'alpli à un ami. Le seul problème, c'est que çà charge éternellement mais que ca ne se connecte pas...

    Merci pour vos idées!!!

    • Partager sur Facebook
    • Partager sur Twitter
      5 juin 2019 à 18:49:27

      Normal , l'adresse donnee dans le cours doit etre l'adresse du localhost (127.0.0.1) , qui est une adresse qui veut dire en gros : "le host est sur la meme machine ". Si tu veux distribuer tu devra soit :
      - Fournir ton adresse ip personnel au logiciel distribuer afin qu'il se connecte a toi directement ..
      - Heberger le serveur sur un serveur distant et te connecter dessus avec la bonne ip.
      • Partager sur Facebook
      • Partager sur Twitter
        6 juin 2019 à 9:12:13

        J'ai fournis mon IP interne au logiciel client, et pourtant cela ne fonctionne pas! Auriez vous d'autres idées de la où peu venir le bug?

        • Partager sur Facebook
        • Partager sur Twitter
          6 juin 2019 à 9:38:59

          Tu manques de connaissance question réseau. C'est pas aussi simple.

          Si ton ami n'est pas dans le même réseau que toi il y a du NAT à faire. Par exemple, chez toi à la maison tu as une box (orange, bouygues, numisérable, etc) qui a une adresse ip publique. Mais derrière, tu as un réseau local privé (en général les adresses 192.*). Ces adresses ne sont pas routables sur internet. Ainsi, tu dois configurer ta box pour qu'un port TCP/UDP soit affecté à ton adresse dans ton réseau local. Et pour compliquer les choses, ta box fait un serveur DHCP donc ton adresse locale n'est jamais la même (ni même celle de la box).

          Tout ça pour dire que :

          • Tu dois d'abord faire en sorte d'avoir une adresse ip locale fixe (ça se configure sur la plupart des box via l'adresse mac)
          • Tu dois affecter un port pour le rediriger sur cette ip locale
          • Tu dois donner ton adresse ip publique à ton ami (cette adresse peut changer d'un jour à l'autre).
          • Partager sur Facebook
          • Partager sur Twitter

          git is great because Linus did it, mercurial is better because he didn't.

            6 juin 2019 à 11:34:03

            Merci pour tous tes conseils, mais mon adresse IP public ne semble pas bouger: c'est la même depuis 4-5 jours, de même pour mon ip local... De plus mon ami a mon ip public, je ne vois donc pas ou est le problème.

            PS: j'ai aussi essayer de communiquer avec un autre ordi de ma maison, j'ai rentré mon ip local, et la connexion ne se faisait pas non plus...

            Si vous avez d'autres idées, je suis preneur !

            -
            Edité par PieWar 6 juin 2019 à 11:37:14

            • Partager sur Facebook
            • Partager sur Twitter
              6 juin 2019 à 14:48:56

              Sans code on ne pourra pas aider.
              • Partager sur Facebook
              • Partager sur Twitter

              git is great because Linus did it, mercurial is better because he didn't.

                6 juin 2019 à 18:36:28

                Voici mon code:

                Pour le client:

                fenetreclient.h:

                #ifndef FENETRECLIEN_H
                #define FENETRECLIEN_H
                
                #include <QMainWindow>
                #include <QtNetwork>
                #include<QApplication>
                #include<QTcpSocket>
                #include<QTcpServer>
                #include "ui_fenetreclien.h"
                #include<QWidget>
                
                namespace Ui
                {
                class FenetreClien;
                }
                
                class FenetreClien : public QMainWindow
                {
                    Q_OBJECT
                
                public:
                    explicit FenetreClien(QWidget *parent = nullptr);
                    ~FenetreClien();
                private slots:
                    void boutonConnection_cilque();
                    void boutonEnvoyer_clique();
                    void message_entre();
                    void arriveeMsg();
                    void connection();
                    void deconnection();
                    void erreurSocket();
                private:
                    Ui::FenetreClien *ui;
                    QTcpSocket *socket;
                    quint16 tailleMessage=0;
                };
                
                #endif // FENETRECLIEN_H
                


                fenetreclient.cpp:

                #include "fenetreclien.h"
                #include "ui_fenetreclien.h"
                
                FenetreClien::FenetreClien(QWidget *parent) :
                    QMainWindow(parent),
                    ui(new Ui::FenetreClien)
                {
                    ui->setupUi(this);
                    socket = new QTcpSocket(this);
                    connect(socket, SIGNAL(readyRead()), this, SLOT(arriveeMsg()));
                    connect(socket, SIGNAL(connected()), this, SLOT(connection()));
                    connect(socket, SIGNAL(disconnected()), this, SLOT(deconnection()));
                    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(erreurSocket(QAbstractSocket::SocketError)));
                }
                
                FenetreClien::~FenetreClien()
                {
                    delete ui;
                    deconnection();
                }
                void FenetreClien::boutonConnection_cilque()
                {
                    ui->textEdit->append(tr("<em>Tentative de connection en cours...</em>"));
                    ui->boutonConnection->setEnabled(false);
                    socket->abort();
                    socket->connectToHost(ui->adresseIPServeur->text(),ui->portEntreeServeur->value());
                }
                void FenetreClien::boutonEnvoyer_clique()
                {
                    QByteArray paquet;
                    QDataStream messageSortant(&paquet,QIODevice::WriteOnly);
                    QString messageAEnvoyer=tr("<strong>")+ui->nomUtilisateur->text()+tr(": </strong>")+ui->message->text();
                    messageSortant<<quint16(0);
                    messageSortant<<messageAEnvoyer;
                    messageSortant.device()->seek(0);
                    messageSortant<<quint16(paquet.size()-sizeof (quint16));
                    socket->write(paquet);
                    ui->message->clear();
                    ui->message->setFocus();
                }
                void FenetreClien::message_entre()
                {
                    boutonEnvoyer_clique();
                }
                void FenetreClien::arriveeMsg()
                {
                
                        QDataStream messageEntrant(socket);
                
                        if (tailleMessage == 0)
                        {
                            if (socket->bytesAvailable() < (int)sizeof(quint16))
                                 return;
                
                            messageEntrant >> tailleMessage;
                        }
                
                        if (socket->bytesAvailable() < tailleMessage)
                            return;
                
                        QString messageRecu;
                        messageEntrant >> messageRecu;
                
                        ui->textEdit->append(messageRecu);
                
                        tailleMessage = 0;
                }
                void FenetreClien::connection()
                {
                    ui->textEdit->append(tr("<em>Vous etes connectés!</em>"));
                    ui->boutonConnection->setEnabled(true);
                    ui->textEdit->setEnabled(true);
                    ui->boutonEnvoiMessage->setEnabled(true);
                }
                void FenetreClien::deconnection()
                {
                    ui->textEdit->append(tr("<em>Vous etes deconnecté</em>"));
                }
                void FenetreClien::erreurSocket()
                {
                    ui->textEdit->append(tr("<em>Erreur:")+socket->errorString()+tr(".</em>"));
                }
                


                main.cpp:

                #include "fenetreclien.h"
                #include <QApplication>
                
                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                    FenetreClien fenClient;
                    fenClient.show();
                
                    return a.exec();
                }
                

                fenetreclien.ui:


                Pour le serveur:

                fenetreserveur.h:

                #ifndef FENETRESERVEUR_H
                #define FENETRESERVEUR_H
                #include<QFile>
                #include <QObject>
                #include <QWidget>
                #include<QLabel>
                #include<QPushButton>
                #include<QTcpServer>
                #include<QTcpSocket>
                #include<QApplication>
                #include<QVBoxLayout>
                #include<QTextStream>
                #include<fstream>
                #include<string>
                #include<ctime>
                
                class fenetreServeur: public QWidget
                {
                    Q_OBJECT
                public:
                    fenetreServeur();
                    void envoyerMessage(const QString & message);
                private slots:
                    void nouvelleConnection();
                    void recevoirDonnes();
                    void deconnection();
                
                private:
                    QLabel *etatServeur;
                    QPushButton *fermetureServeur;
                    QTcpServer *serveur;
                    QList<QTcpSocket *> clients;
                    quint16 tailleMessage;
                
                };
                
                #endif // FENETRESERVEUR_H
                

                fenetreserveur.cpp:

                #include "fenetreserveur.h"
                using namespace std;
                fenetreServeur::fenetreServeur()
                {
                    etatServeur=new QLabel;
                    fermetureServeur=new QPushButton("Fermer le serveur");
                    QObject::connect(fermetureServeur,SIGNAL(clicked()),qApp,SLOT(quit()));
                    QVBoxLayout *lay=new QVBoxLayout;
                    lay->addWidget(etatServeur);
                    lay->addWidget(fermetureServeur);
                    setLayout(lay);
                    setWindowTitle(tr("Serveur"));
                    serveur= new QTcpServer(this);
                    if(!serveur->listen(QHostAddress::Any,21))
                    {
                        etatServeur->setText(tr("Le serveur n'a pas pu se lancer!\n")+serveur->errorString());
                    }
                    else
                    {
                        etatServeur->setText(tr("Le serveur s'est lancé sur le port ") + QString::number(serveur->serverPort()) + tr("\nDes clients peuvent maintenant se connecter."));
                        connect(serveur,SIGNAL(newConnection()),this,SLOT(nouvelleConnection()));
                    }
                    tailleMessage=0;
                }
                void fenetreServeur::nouvelleConnection()
                {
                    envoyerMessage(tr("<em>Un nouvel utilisateur s'est conecté!</em>"));
                    QTcpSocket *nouveauClient=serveur->nextPendingConnection();
                    clients<<nouveauClient;
                    connect(nouveauClient,SIGNAL(readyRead()),this,SLOT(recevoirDonnes()));
                    connect(nouveauClient,SIGNAL(disconnected()),this,SLOT(deconnection()));
                }
                void fenetreServeur::envoyerMessage(const QString &message)
                {
                    ofstream fluxHistorique;
                    fluxHistorique.open("Serveur_Historique.txt",ios::app);
                    string messageStr=message.toStdString();
                    time_t tmm = time(nullptr);
                       char* dt = ctime(&tmm);
                    fluxHistorique<<dt<<messageStr<<endl;
                    QByteArray paquet;
                    QDataStream fluxSortant(&paquet,QIODevice::WriteOnly);
                    fluxSortant<<(quint16)0;
                    fluxSortant<<message;
                    fluxSortant.device()->seek(0);
                    fluxSortant<<(quint16)(unsigned(paquet.size())-sizeof (quint16));
                    for(int numClient=0;numClient<clients.size();numClient++)
                    {
                        clients[numClient]->write(paquet);
                    }
                }
                void fenetreServeur::deconnection()
                {
                    envoyerMessage(tr("<em>Une personne s'est deconnectée!</em>"));
                    QTcpSocket *socket=qobject_cast<QTcpSocket*>(sender());
                    if(socket==nullptr)
                        return;
                    clients.removeOne(socket);
                    socket->deleteLater();
                }
                void fenetreServeur::recevoirDonnes()
                {
                    QTcpSocket *socket=qobject_cast<QTcpSocket*>(sender());
                    if(socket==nullptr)
                        return;
                    QDataStream fluxEntrant(socket);
                    if(tailleMessage==0)
                    {
                        if(socket->bytesAvailable()<(int)sizeof(quint16))
                            return;
                        fluxEntrant>>tailleMessage;
                    }
                    if(socket->bytesAvailable()<tailleMessage)
                        return;
                    QString message;
                    fluxEntrant>>message;
                    envoyerMessage(message);
                    tailleMessage=0;
                }
                

                et enfin le main.cpp:

                #include <QApplication>
                #include "fenetreserveur.h"
                
                int main(int argc, char* argv[])
                {
                    QApplication app(argc, argv);
                
                    fenetreServeur fenetre;
                    fenetre.show();
                
                    return app.exec();
                }
                

                Somme toutes c'est presque la même chose que le code de Mathieu Nebra, mon seul ajout, c'est un fichier qui fait usage d'historique.
                Merci d'avance pour le temps que vous avez prendri pour tout lire!

                • Partager sur Facebook
                • Partager sur Twitter
                  11 juin 2019 à 10:03:57

                  >De plus mon ami a mon ip public, je ne vois donc pas ou est le problème.

                  C'est l'adresse ip de votre Box, pas de votre machine.

                  Il faut NATer pour que votre box transfert les données de l'extérieur vers votre machine et que vos réponses au niveau du serveur fasse le chemin inverse.

                  >j'ai rentré mon ip local, et la connexion ne se faisait pas non plus...

                  Et les firewalls, ils mettent le chocolat dans le papier d'alu ?

                  Vous semblez bien tendre pour faire du réseau à votre niveau d'apprentissage.

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                    12 juin 2019 à 15:03:44

                    Est-ce que le part-feu du client peu poser problème?

                    • Partager sur Facebook
                    • Partager sur Twitter
                      12 juin 2019 à 16:03:42

                      >Est-ce que le part-feu du client peu poser problème?

                      Bin oui.

                      Bien venu dans le monde merveilleux du réseau.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                        13 juin 2019 à 15:54:32

                        Et du coup comment faire pour contourner ces problèmes? Ca va juste afficher un message de danger?

                        Excuses moi pour ces questions, je débute.

                        PS: tu aurais un bon tuto pour faire des applications utilisant le réseau?

                        • Partager sur Facebook
                        • Partager sur Twitter
                          13 juin 2019 à 16:02:45

                          Tu peux désactiver le parefeu temporairement le temps de tester pour voir si c'est bien ça le problème.

                          Sinon il existe des outils en ligne de commande qui permettent un peu de tout tester avant de directement passer par ton application. Par exemple avec telnet tu peux déjà voir si tu arrives au moins à te connecter sur le serveur en TCP. Et si c'est le cas et que tu vois un client côté serveur ça veut dire que ton appli cliente a un problème.

                          Il faut toujours faire par petites étapes. 

                          • Partager sur Facebook
                          • Partager sur Twitter

                          git is great because Linus did it, mercurial is better because he didn't.

                            13 juin 2019 à 17:48:05

                            Généralement, on se prend pas la tête, on utilise une architecture réseau qui a fait ses preuves, comme un serveur central qui accepte des connexion des clients.

                            Généralement, le connexion du client derrière une box vers un serveur extérieur est déjà configuré pour passer (facilement configurable par un utilisateur lambda ou un programme d'installation du client).

                            L'utilisation du port 80 (protocole HTTP) ou 443 (protocole HTTPS) sont généralement plus facile que les autres.

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                            Diffuser un programme utilisant le résau

                            × 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