Results 1 to 2 of 2

Thread: QSslSocket fails to connect to my server.

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    Default QSslSocket fails to connect to my server.

    Hi, I would like to make a secure connection to my server, so I've tried this :

    Here is the implementation of the server :

    Qt Code:
    1. #include "fenserveur.h"
    2. #include <iostream>
    3. FenServeur::FenServeur()
    4.  
    5. {
    6.  
    7. serveur = new AncServeur(this);
    8. if (!serveur->listen(QHostAddress::Any, 50885)) // Démarrage du serveur sur toutes les IP disponibles et sur le port 50585
    9. {
    10. std::cout<<"Le serveur n'a pas pu être démarré. Raison :<br />"<<serveur->errorString().toStdString();
    11. }
    12. else
    13. {
    14. // Si le serveur a été démarré correctement
    15. std::cout<<"Le serveur a été démarré sur le port : "<<QString::number(serveur->serverPort()).toStdString()<<" Des clients peuvent maintenant se connecter."<<std::endl;
    16. connect(serveur, SIGNAL(nouveauClient(ClientServeur*)), this, SLOT(nouvelleConnexion(ClientServeur*)));
    17. connect(serveur, SIGNAL(sslErreur(const QString &)),this, SLOT(sslErreur(const QString &)) );
    18. }
    19.  
    20.  
    21. }
    22. //on affiche les erreurs ssl
    23. void FenServeur::sslErreur(const QString &erreur)
    24. {
    25. std::cout<<"erreur : "<<erreur.toStdString()<<std::endl;
    26. }
    27. void FenServeur::nouvelleConnexion(ClientServeur* nouveauClient)
    28.  
    29. {
    30.  
    31. envoyerATous("Un nouveau client vient de se connecter");
    32.  
    33. connect(nouveauClient, SIGNAL(readyRead()), this, SLOT(donneesRecues()));
    34.  
    35. connect(nouveauClient, SIGNAL(disconnected()), this, SLOT(deconnexionClient()));
    36.  
    37. }
    38.  
    39.  
    40. void FenServeur::donneesRecues()
    41.  
    42. {
    43.  
    44. // 1 : on reçoit un paquet (ou un sous-paquet) d'un des clients
    45.  
    46.  
    47. // On détermine quel client envoie le message (recherche du QTcpSocket du client)
    48.  
    49. QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
    50.  
    51. if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
    52.  
    53. return;
    54.  
    55.  
    56. // Si tout va bien, on continue : on récupère le message
    57.  
    58. QDataStream in(socket);
    59.  
    60.  
    61. if (tailleMessage == 0) // Si on ne connaît pas encore la taille du message, on essaie de la récupérer
    62.  
    63. {
    64.  
    65. if (socket->bytesAvailable() < (int)sizeof(quint16)) // On n'a pas reçu la taille du message en entier
    66.  
    67. return;
    68.  
    69.  
    70. in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
    71.  
    72. }
    73.  
    74.  
    75. // Si on connaît la taille du message, on vérifie si on a reçu le message en entier
    76.  
    77. if (socket->bytesAvailable() < tailleMessage) // Si on n'a pas encore tout reçu, on arrête la méthode
    78.  
    79. return;
    80.  
    81.  
    82.  
    83. // Si ces lignes s'exécutent, c'est qu'on a reçu tout le message : on peut le récupérer !
    84.  
    85. QString message;
    86.  
    87. in >> message;
    88.  
    89.  
    90.  
    91. // 2 : on renvoie le message à tous les clients
    92.  
    93. envoyerATous(message);
    94.  
    95.  
    96. // 3 : remise de la taille du message à 0 pour permettre la réception des futurs messages
    97.  
    98. tailleMessage = 0;
    99.  
    100. }
    101.  
    102.  
    103. void FenServeur::deconnexionClient()
    104.  
    105. {
    106.  
    107. envoyerATous("Un client vient de se déconnecter");
    108.  
    109.  
    110. // On détermine quel client se déconnecte
    111.  
    112. QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
    113.  
    114. if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
    115.  
    116. return;
    117.  
    118.  
    119. clients.removeOne(socket);
    120.  
    121.  
    122. socket->deleteLater();
    123.  
    124. }
    125.  
    126.  
    127. void FenServeur::envoyerATous(const QString &message)
    128.  
    129. {
    130.  
    131. // Préparation du paquet
    132.  
    133. QByteArray paquet;
    134.  
    135. QDataStream out(&paquet, QIODevice::WriteOnly);
    136.  
    137.  
    138. out << (quint16) 0; // On écrit 0 au début du paquet pour réserver la place pour écrire la taille
    139.  
    140. out << message; // On ajoute le message à la suite
    141.  
    142. out.device()->seek(0); // On se replace au début du paquet
    143.  
    144. out << (quint16) (paquet.size() - sizeof(quint16)); // On écrase le 0 qu'on avait réservé par la longueur du message
    145.  
    146.  
    147.  
    148. // Envoi du paquet préparé à tous les clients connectés au serveur
    149.  
    150. for (int i = 0; i < clients.size(); i++)
    151.  
    152. {
    153.  
    154. clients[i]->write(paquet);
    155.  
    156. }
    157.  
    158.  
    159. }
    To copy to clipboard, switch view to plain text mode 

    And here, the implementation of my client :

    Qt Code:
    1. #include "fenclient.h"
    2. #include <iostream>
    3.  
    4. FenClient::FenClient()
    5.  
    6. {
    7.  
    8.  
    9. //on instancie un QSslSocket
    10.  
    11. socket = new QSslSocket(this);
    12.  
    13. //on connect les différents signaux
    14.  
    15. connect(socket, SIGNAL(encrypted()), this, SLOT(ready()));
    16.  
    17. connect(socket, SIGNAL(readyRead()), this, SLOT(donneesRecues()));
    18.  
    19. connect(socket, SIGNAL(connected()), this, SLOT(connecte()));
    20.  
    21. connect(socket, SIGNAL(disconnected()), this, SLOT(deconnecte()));
    22.  
    23.  
    24. //on charge la clé privé du client
    25.  
    26. QFile file( "client-key.pem" );
    27.  
    28. if( ! file.open( QIODevice::ReadOnly ) )
    29.  
    30. {
    31.  
    32. qDebug() << "la clé du client ne peut pas être chargé" <<"client-key.pem";
    33.  
    34. return;
    35.  
    36. }
    37.  
    38. QSslKey key( &file, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "****************" );
    39.  
    40. file.close();
    41.  
    42. socket->setPrivateKey( key );
    43.  
    44.  
    45.  
    46. //on charge le certificat du client
    47.  
    48. socket-> setLocalCertificate( "client-crt.pem" );
    49.  
    50.  
    51.  
    52. //on charge le certificat de notre ca
    53.  
    54. if( ! socket->addCaCertificates( "ca/ca.pem" ) )
    55.  
    56. {
    57.  
    58. qDebug() << "ouverture du certificat de la ca impossible" << "ca/ca.pem";
    59.  
    60. return;
    61.  
    62. }
    63.  
    64. //on supprime la vérification du serveur
    65.  
    66. socket->setPeerVerifyMode(QSslSocket::VerifyNone);
    67.  
    68.  
    69.  
    70. //on ignore les erreurs car on a un certificat auto signé
    71.  
    72. socket->ignoreSslErrors();
    73.  
    74.  
    75.  
    76. // On désactive les connexions précédentes s'il y en a
    77.  
    78. socket->abort();
    79.  
    80.  
    81.  
    82.  
    83.  
    84. }
    85. void FenClient::ready() {
    86. //on se connecte au serveur
    87.  
    88. socket->connectToHostEncrypted("127.0.0.1", 50885);
    89.  
    90.  
    91. //on commence l'encryptage
    92.  
    93. socket->startClientEncryption();
    94. envoyerMessage("Test");
    95. }
    96.  
    97. void FenClient::envoyerMessage(const QString& message) {
    98. // Préparation du paquet
    99. QByteArray paquet;
    100.  
    101. QDataStream out(&paquet, QIODevice::WriteOnly);
    102.  
    103.  
    104. out << (quint16) 0; // On écrit 0 au début du paquet pour réserver la place pour écrire la taille
    105.  
    106. out << message; // On ajoute le message à la suite
    107.  
    108. out.device()->seek(0); // On se replace au début du paquet
    109.  
    110. out << (quint16) (paquet.size() - sizeof(quint16)); // On écrase le 0 qu'on avait réservé par la longueur du message
    111.  
    112. socket->write(paquet);
    113. }
    114.  
    115. // On a reçu un paquet (ou un sous-paquet)
    116.  
    117. void FenClient::donneesRecues()
    118.  
    119. {
    120.  
    121. /* Même principe que lorsque le serveur reçoit un paquet :
    122.  
    123.   On essaie de récupérer la taille du message
    124.  
    125.   Une fois qu'on l'a, on attend d'avoir reçu le message entier (en se basant sur la taille annoncée tailleMessage)
    126.  
    127.   */
    128.  
    129. QDataStream in(socket);
    130.  
    131.  
    132. if (tailleMessage == 0)
    133.  
    134. {
    135.  
    136. if (socket->bytesAvailable() < (int)sizeof(quint16))
    137.  
    138. return;
    139.  
    140.  
    141. in >> tailleMessage;
    142.  
    143. }
    144.  
    145.  
    146. if (socket->bytesAvailable() < tailleMessage)
    147.  
    148. return;
    149.  
    150.  
    151.  
    152. // Si on arrive jusqu'à cette ligne, on peut récupérer le message entier
    153.  
    154. QString messageRecu;
    155.  
    156. in >> messageRecu;
    157.  
    158. std::cout<<messageRecu.toStdString()<<std::endl;
    159.  
    160. // On remet la taille du message à 0 pour pouvoir recevoir de futurs messages
    161.  
    162. tailleMessage = 0;
    163.  
    164. }
    165.  
    166.  
    167. // Ce slot est appelé lorsque la connexion au serveur a réussi
    168.  
    169. void FenClient::connecte()
    170.  
    171. {
    172.  
    173. std::cout<<"Connection réussie!"<<std::endl;
    174.  
    175. }
    176.  
    177.  
    178. // Ce slot est appelé lorsqu'on est déconnecté du serveur
    179.  
    180. void FenClient::deconnecte()
    181.  
    182. {
    183.  
    184. std::cout<<"Déconnecté du serveur"<<std::endl;
    185.  
    186. }
    187.  
    188.  
    189. // Ce slot est appelé lorsqu'il y a une erreur
    190.  
    191. void FenClient::erreurSocket(QAbstractSocket::SocketError erreur)
    192.  
    193. {
    194.  
    195. switch(erreur) // On affiche un message différent selon l'erreur qu'on nous indique
    196.  
    197. {
    198.  
    199. case QAbstractSocket::HostNotFoundError:
    200.  
    201. std::cout<<"ERREUR : le serveur n'a pas pu être trouvé. Vérifiez l'IP et le port."<<std::endl;
    202.  
    203. break;
    204.  
    205. case QAbstractSocket::ConnectionRefusedError:
    206.  
    207. std::cout<<"ERREUR : le serveur a refusé la connexion. Vérifiez si le programme \"serveur\" a bien été lancé. Vérifiez aussi l'IP et le port."<<std::endl;
    208.  
    209. break;
    210.  
    211. case QAbstractSocket::RemoteHostClosedError:
    212.  
    213. std::cout<<"ERREUR : le serveur a coupé la connexion."<<std::endl;
    214.  
    215. break;
    216.  
    217. default:
    218.  
    219. std::cout<<"ERREUR : "<<socket->errorString().toStdString()<<std::endl;
    220.  
    221. }
    222.  
    223. }
    To copy to clipboard, switch view to plain text mode 

    The server start and listen to the port, but when I want to connect the client, it fails and I get this error message :

    QSslSocket : cannot resolve SSLv2_client_method
    QSslSocket : cannot resolve SSLv2_server_method

    Thanks for your help.

    PS : My os is unbuntu 14.04
    Last edited by LaurentDuroisin; 23rd January 2016 at 09:00.

Similar Threads

  1. Problem with QSslSocket Server app
    By orcher in forum Qt Programming
    Replies: 0
    Last Post: 3rd April 2014, 09:13
  2. Replies: 15
    Last Post: 11th March 2014, 01:54
  3. Replies: 2
    Last Post: 9th May 2011, 10:38
  4. Replies: 3
    Last Post: 29th November 2009, 20:24
  5. QSslSocket server
    By tpf80 in forum Qt Programming
    Replies: 3
    Last Post: 7th May 2009, 04:10

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.