Results 1 to 2 of 2

Thread: QSslSocket fails to connect to my server.

  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.

  2. #2

    Default Re: QSslSocket fails to connect to my server.

    Hi!
    Now it's connecting but no data is sent to the server.
    Solved, I've just forgotten to initialize the tailleMessage var to 0.
    Last edited by LaurentDuroisin; 23rd January 2016 at 11:58.

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.