Results 1 to 4 of 4

Thread: QSslSocket server

  1. #1
    Join Date
    Oct 2006
    Location
    Hawaii
    Posts
    130
    Thanks
    48
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QSslSocket server

    Hi, I have been experimenting with the Simple Chat example at Here and have decided as an exercise to learn more about SSL sockets, to convert it into an encrypted simple chat. So far I am stuck at a compile error in the server part:

    error: invalid conversion from ‘QTcpSocket*’ to ‘QSslSocket*’
    This is caused by the following code:
    Qt Code:
    1. QSslSocket* connection = nextPendingConnection();
    To copy to clipboard, switch view to plain text mode 

    So it seems as if nextPendingConnection() returns a QTcpSocket, and that I need to reimplement in order to make it work for the SSL connections, however I have no idea where to begin with this or even if I am going in the right direction. It looks like there isn't a "QTcpServer" equivalent for SSL.

  2. #2
    Join Date
    Jan 2006
    Location
    Napoli, Italy
    Posts
    621
    Thanks
    5
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSslSocket server

    From QSslSocket documentation you read

    An example of using the delayed SSL handshake to secure an existing connection is the case where an SSL server secures an incoming connection. Suppose you create an SSL server class as a subclass of QTcpServer. You would override QTcpServer::incomingConnection() with something like the example below, which first constructs an instance of QSslSocket and then calls setSocketDescriptor() to set the new socket's descriptor to the existing one passed in. It then initiates the SSL handshake by calling startServerEncryption().
    Qt Code:
    1. void SslServer::incomingConnection(int socketDescriptor)
    2. {
    3. QSslSocket *serverSocket = new QSslSocket;
    4. if (serverSocket->setSocketDescriptor(socketDescriptor)) {
    5. connect(serverSocket, SIGNAL(encrypted()), this, SLOT(ready()));
    6. serverSocket->startServerEncryption();
    7. } else {
    8. delete serverSocket;
    9. }
    10. }
    To copy to clipboard, switch view to plain text mode 
    A camel can go 14 days without drink,
    I can't!!!

  3. #3
    Join Date
    Oct 2006
    Location
    Hawaii
    Posts
    130
    Thanks
    48
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSslSocket server

    Yeah.. I read this very piece of code from the manual before I posted.

    I am just not quite sure how the functionality of incomingConnection() relates to the functionality of nextPendingConnection() such that I can rework that part of the program. I will take a look at the Qt source for these functions later on and see if I cant see what is different about the suggested incomingConnection() in the manual for SSL, and the original non-ssl are, which should give me a clue as to what to do about incommingConnection() hopefully.

  4. #4
    Join Date
    Oct 2006
    Location
    Hawaii
    Posts
    130
    Thanks
    48
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSslSocket server

    Ok I think I am close, but just need a nudge in the right direction. Heres the modified code for the client and server so far:

    Client:
    Qt Code:
    1. SimpleChatClient::SimpleChatClient(QWidget* parent, Qt::WFlags flags) : QWidget(parent, flags) {
    2.  
    3.  
    4. QVBoxLayout* main = new QVBoxLayout(this);
    5.  
    6.  
    7. QHBoxLayout* bottom = new QHBoxLayout;
    8.  
    9.  
    10.  
    11. QLabel* label = new QLabel("Server:", this);
    12.  
    13. server = new QLineEdit(this);
    14.  
    15. port = new QSpinBox(this);
    16.  
    17. conn = new QPushButton("Connect", this);
    18.  
    19. port->setRange(1, 32767);
    20.  
    21. port->setValue(DEFAULT_PORT);
    22.  
    23. server->setText("localhost");
    24.  
    25. top->addWidget(label, 0, 0);
    26.  
    27. top->addWidget(server, 0, 1);
    28.  
    29. top->addWidget(port, 0, 2);
    30.  
    31.  
    32.  
    33. label = new QLabel("Nick:", this);
    34.  
    35. nick = new QLineEdit(this);
    36.  
    37. nick->setText("Anonymous");
    38.  
    39. top->addWidget(label, 1, 0);
    40.  
    41. top->addWidget(nick, 1, 1);
    42.  
    43. top->addWidget(conn, 1, 2);
    44.  
    45.  
    46.  
    47. chat = new QTextEdit(this);
    48.  
    49. chat->setReadOnly(true);
    50.  
    51.  
    52.  
    53. label = new QLabel("Message:", this);
    54.  
    55. message = new QLineEdit(this);
    56.  
    57. send = new QPushButton("Send", this);
    58.  
    59. send->setDefault(true);
    60.  
    61. bottom->addWidget(label);
    62.  
    63. bottom->addWidget(message);
    64.  
    65. bottom->addWidget(send);
    66.  
    67.  
    68.  
    69. main->addLayout(top);
    70.  
    71. main->addWidget(chat);
    72.  
    73. main->addLayout(bottom);
    74.  
    75. setLayout(main);
    76.  
    77.  
    78.  
    79. buffer = new QBuffer(this);
    80.  
    81. socket = new QSslSocket(this);
    82.  
    83. buffer->open(QIODevice::ReadWrite);
    84.  
    85.  
    86.  
    87. connect(message, SIGNAL(returnPressed()), SLOT(sendMessage()));
    88.  
    89. connect(send, SIGNAL(clicked()), SLOT(sendMessage()));
    90.  
    91. connect(conn, SIGNAL(clicked()), SLOT(toggleConnection()));
    92.  
    93.  
    94.  
    95. connect(socket, SIGNAL(connected()), SLOT(setConnected()));
    96.  
    97. connect(socket, SIGNAL(disconnected()), SLOT(setDisconnected()));
    98.  
    99. connect(socket, SIGNAL(readyRead()), SLOT(receiveMessage()));
    100.  
    101. connect(socket, SIGNAL(encrypted()), this, SLOT(connectionReady()));
    102.  
    103.  
    104. setDisconnected();
    105.  
    106. }
    107.  
    108. void SimpleChatClient::connectionReady() {
    109. qDebug() << "Connection is encrypted! ";
    110. }
    111.  
    112.  
    113.  
    114. SimpleChatClient::~SimpleChatClient() {
    115.  
    116. buffer->close();
    117.  
    118. }
    119.  
    120.  
    121.  
    122. void SimpleChatClient::setConnected() {
    123. qDebug() << "Connected! ";
    124.  
    125. port->setEnabled(false);
    126.  
    127. server->setEnabled(false);
    128.  
    129. nick->setEnabled(true);
    130.  
    131. message->setEnabled(true);
    132.  
    133. chat->setEnabled(true);
    134.  
    135. chat->clear();
    136.  
    137. send->setEnabled(true);
    138.  
    139. conn->setText("Disconnect");
    140.  
    141. }
    142.  
    143.  
    144.  
    145. void SimpleChatClient::setDisconnected() {
    146. qDebug() << "Disconnected! ";
    147.  
    148. port->setEnabled(true);
    149.  
    150. server->setEnabled(true);
    151.  
    152. nick->setEnabled(false);
    153.  
    154. message->setEnabled(false);
    155.  
    156. chat->setEnabled(false);
    157.  
    158. send->setEnabled(false);
    159.  
    160. conn->setText("Connect");
    161.  
    162. }
    163.  
    164.  
    165.  
    166. void SimpleChatClient::toggleConnection() {
    167.  
    168. if (socket->state() == QAbstractSocket::UnconnectedState) {
    169. qDebug() << "Connecting! ";
    170.  
    171. socket->connectToHostEncrypted(server->text(), port->value());
    172.  
    173. } else {
    174. qDebug() << "Disconnecting! ";
    175.  
    176. socket->disconnectFromHost();
    177.  
    178. }
    179.  
    180. }
    181.  
    182.  
    183.  
    184. void SimpleChatClient::sendMessage() {
    185.  
    186. // "<nick> message\n"
    187.  
    188. socket->write("<" + nick->text().toLatin1() + "> " + message->text().toLatin1() + "\n");
    189.  
    190. message->clear();
    191.  
    192. }
    193.  
    194.  
    195.  
    196. void SimpleChatClient::receiveMessage() {
    197.  
    198. // missing some checks for returns values for the sake of simplicity
    199.  
    200. qint64 bytes = buffer->write(socket->readAll());
    201.  
    202. // go back as many bytes as we just wrote so that it can be read
    203.  
    204. buffer->seek(buffer->pos() - bytes);
    205.  
    206. // read only full lines, line by line
    207.  
    208. while (buffer->canReadLine()) {
    209.  
    210. QString line = buffer->readLine();
    211.  
    212. chat->append(line.simplified());
    213.  
    214. }
    215.  
    216. }
    To copy to clipboard, switch view to plain text mode 
    Server:
    Qt Code:
    1. SimpleChatServer::SimpleChatServer(QObject* parent) : QTcpServer(parent) {
    2.  
    3. connect(this, SIGNAL(newConnection()), this, SLOT(addConnection()));
    4.  
    5. }
    6.  
    7.  
    8.  
    9. SimpleChatServer::~SimpleChatServer() {
    10.  
    11.  
    12. }
    13.  
    14. ////////////////////////////////////////////////////////////////////////////////////////////////
    15.  
    16.  
    17.  
    18. QSslSocket *SimpleChatServer::nextPendingConnection() {
    19.  
    20. if (pendingConnections.isEmpty())
    21.  
    22. return 0;
    23.  
    24.  
    25.  
    26. return pendingConnections.takeFirst();
    27.  
    28. }
    29.  
    30. void SimpleChatServer::incomingConnection(int socketDescriptor) {
    31. qDebug() << "New Connection! ";
    32. QSslSocket *serverSocket = new QSslSocket;
    33. if (serverSocket->setSocketDescriptor(socketDescriptor)) {
    34. qDebug() << "Socket Descriptor Set! ";
    35. connect(serverSocket, SIGNAL(encrypted()), this, SLOT(connectionReady()));
    36. serverSocket->startServerEncryption();
    37. pendingConnections.append(serverSocket);
    38. } else {
    39. qDebug() << "Socket Descriptor Not Set! ";
    40. delete serverSocket;
    41. }
    42. }
    43.  
    44. void SimpleChatServer::connectionReady() {
    45. qDebug() << "Connection is encrypted! ";
    46. }
    47.  
    48. ////////////////////////////////////////////////////////////////////////////////////////////////
    49.  
    50.  
    51.  
    52. void SimpleChatServer::addConnection() {
    53. qDebug() << "Connection added to list! ";
    54.  
    55. QSslSocket* connection = nextPendingConnection();
    56.  
    57. connections.append(connection);
    58.  
    59. QBuffer* buffer = new QBuffer(this);
    60.  
    61. buffer->open(QIODevice::ReadWrite);
    62.  
    63. buffers.insert(connection, buffer);
    64.  
    65. connect(connection, SIGNAL(disconnected()), SLOT(removeConnection()));
    66.  
    67. connect(connection, SIGNAL(readyRead()), SLOT(receiveMessage()));
    68.  
    69. }
    70.  
    71.  
    72.  
    73. void SimpleChatServer::removeConnection() {
    74. qDebug() << "Disconnected! ";
    75.  
    76. QSslSocket* socket = static_cast<QSslSocket*>(sender());
    77.  
    78. QBuffer* buffer = buffers.take(socket);
    79.  
    80. buffer->close();
    81.  
    82. buffer->deleteLater();
    83.  
    84. connections.removeAll(socket);
    85.  
    86. socket->deleteLater();
    87.  
    88. }
    89.  
    90.  
    91.  
    92. void SimpleChatServer::receiveMessage() {
    93.  
    94. QSslSocket* socket = static_cast<QSslSocket*>(sender());
    95.  
    96. QBuffer* buffer = buffers.value(socket);
    97.  
    98.  
    99.  
    100. // missing some checks for returns values for the sake of simplicity
    101. qDebug() << "Reading From: " << socket;
    102.  
    103. qint64 bytes = buffer->write(socket->readAll());
    104.  
    105. //now we have a buffer containing the data incomming from the socket
    106.  
    107. // go back as many bytes as we just wrote so that it can be read
    108.  
    109. buffer->seek(buffer->pos() - bytes);
    110.  
    111.  
    112.  
    113.  
    114. // read only full lines, line by line
    115.  
    116. while (buffer->canReadLine()) {
    117.  
    118.  
    119. QByteArray line = buffer->readLine();
    120.  
    121. //this list holds the sockets currently connected:
    122.  
    123. foreach (QSslSocket* connection, connections) {
    124. qDebug() << "Writing to: " << connection;
    125.  
    126. connection->write(line);
    127.  
    128.  
    129. }
    130.  
    131. }
    132.  
    133. }
    To copy to clipboard, switch view to plain text mode 

    On the console what shows for the client when I try to connect is:

    Connecting!
    Connected!
    Disconnected!
    On the server at the same time it shows:

    New Connection!
    Socket Descriptor Set!
    Connection added to list!
    Disconnected!
    So it seems that both the client and server are communicating, but I notice that neither of them are firing the encrypted() signal, and they immediately disconnect. What could I be missing?

Similar Threads

  1. Replies: 3
    Last Post: 29th November 2009, 20:24
  2. QSslSocket problem
    By The Storm in forum Qt Programming
    Replies: 5
    Last Post: 23rd March 2008, 12:58
  3. QSslSocket problems
    By TheOnlyDan in forum Qt Programming
    Replies: 6
    Last Post: 27th September 2007, 11:54
  4. How to ping a server ?
    By Nyphel in forum Newbie
    Replies: 2
    Last Post: 23rd April 2007, 11:27
  5. How a server can write "Hello" to a browser ?
    By probine in forum Qt Programming
    Replies: 2
    Last Post: 1st December 2006, 14:43

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.