qtmqtt can not connect to server - c++

QtMqtt cannot connect to the server, but I can connect normally using other test software.The server is mosquitto on Ubuntu.
m_client= new QMqttClient(this);
m_client->setProtocolVersion(QMqttClient::MQTT_3_1_1);
m_client->setPort(1883);
m_client->setHostname("127.0.0.1");
m_client->setClientId("qt");
m_client->connectToHost();
connect(m_client,SIGNAL(stateChanged(ClientState)),this,SLOT(slot_stateChanged()),Qt::UniqueConnection);
void slot_stateChanged()
{
qDebug() << "mqtt stsate" << _client->state();
}

you are using a broker at localhost, maybe you should connect the signal slot before calling the connectToHost()
try with
m_client= new QMqttClient(this);
//connect signal slot
connect(m_client,SIGNAL(stateChanged(ClientState)),this,SLOT(slot_stateChanged()),Qt::UniqueConnection);
//connect to borker
m_client->setProtocolVersion(QMqttClient::MQTT_3_1_1);
m_client->setPort(1883);
m_client->setHostname("127.0.0.1");
m_client->setClientId("qt");
m_client->connectToHost();
void slot_stateChanged()
{
qDebug() << "mqtt stsate" << _client->state();
}

Related

Can not start a QTcp Server

I'm having a weird error. I'm trying to establish a connection to a server but the Server doesn't seem to start. Here's the Server.cpp:
Server::Server (QObject *parent) :
QTcpServer(parent)
{
}
void Server::start()
{
QHostAddress pHost;
pHost.setAddress("192.168.10.10"); //Setting the Address of the Server to the Address of the target system
QString printAddress;
printAddress = pHost.toString();
printf(QString("starting Host under " + printAddress + " \n").toStdString().c_str());
if (this->listen(pHost, 8016))
{
printf(QString("Server started and Listening \n").toStdString().c_str());
}
else
{
printf("Server could not be started \n");
}
}
In my main.cpp I instantiate the Server and call the method start.
Server pServer;
pServer.start();
this->listen(pHost, 8016) seems to be returning false because i get "Server could not be started" printed. What am I doing wrong? Why does the Server not start?
By the Way the Address 192.168.10.10 is the Address of another Computer in the local Network. Maybe that's why I'm getting an Error ?
I'm trying to establish a connection to that Device.
Any Help is highly appreciated !! Thank you !!

How to read complete data using QTcpSocket (Qt4.7)

I created a TcpServer in order to receive data from a client. The client sends a lot of messages and I would like to read them. So far my TcpServer.cpp looks like this :
void TcpServer::serverStart()
{
server = new QTcpServer(this);
if (!server->listen(QHostAddress("192.168.x.x"), 48583))
{
qDebug() << "Not listening";
server->close();
delete server;
return;
}
else {
qDebug() << "Listening";
}
connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
}
void TcpServer::newConnection()
{
socket = server->nextPendingConnection();
qDebug() << "Client connected";
connect(socket, SIGNAL(readyRead()), this, SLOT(getData()));
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
}
void TcpServer::getData()
{
QByteArray buffer;
while (socket->bytesAvailable())
{
buffer.append(socket->readAll());
}
qDebug() << buffer;
}
void TcpServer::serverStop()
{
server->close();
delete server;
}
I know my getData function needs a lot more in order to receive everything but I don't understand the steps needed to do that.If someone could give me some pointers I would be grateful !
TCP is a transport protocol which is stream oriented. Imagine it as being a continuous flow of data. There are no messages defined by TCP yet, because once again it is a continuous flow of data.
I'm taking from your comment that you are not using any application layer protocol. You need an application layer protocol, like e.g. http, which is then defining "messages" and giving you further instructions on how to read a complete message.

how to connect to QBluetoothServer

I have a code to listen for bluetooth connections
rfcommServer = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this);
connect(rfcommServer, SIGNAL(newConnection()), this, SLOT(clientConnected()));
bool result = rfcommServer->listen(localAdapter);
how to code the client side of this so thaat clientConnected slot is called?
I found this code
QBluetoothSocket * socket;
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
qDebug() << "Create socket";
socket->connectToService(remoteService);
qDebug() << "ConnectToService done";
where remoteService is declared as QBluetoothServiceInfo &remoteService;
but how do I initialize remoteService?
And can I use rfcommServer->listen(localAdapter); in both client side and server side, because, I want to use both side as server, that is both sides can accept incoming connections.

Failed SSL handshake with ssl server written on Qt 5.2.1

I am writing ssl proxy server using Qt. Here is code sample:
# header
class SslProxyServer : public QTcpServer
{
Q_OBJECT
public:
explicit SslProxyServer(quint16 port, QObject *parent = 0);
private slots:
void onEncrypted();
void onReadyRead();
void onSslErrors(QList<QSslError> sslErrors);
void onModeChanged(QSslSocket::SslMode sslMode);
void onStateChanged(QAbstractSocket::SocketState socketState);
void onError(QAbstractSocket::SocketError socketError);
protected:
void incomingConnection(qintptr socketDescriptor);
};
# source
SslProxyServer::SslProxyServer(quint16 port, QObject *parent) : QTcpServer(parent)
{
if (!listen(QHostAddress::Any, port)) {
qDebug() << "Unable to start tcp server";
return;
}
if (m_tcpServer->isListening()) {
qDebug() << "Listening port" << m_tcpServer->serverPort();
} else {
qDebug() << "Not listening";
}
}
void SslProxyServer::incomingConnection(qintptr socketDescriptor)
{
qDebug() << "incomingConnection";
QSslSocket *serverSocket = new QSslSocket(this);
if (serverSocket->setSocketDescriptor(socketDescriptor)) {
connect(serverSocket, SIGNAL(encrypted()), this, SLOT(onEncrypted()));
connect(serverSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(serverSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(onSslErrors(QList<QSslError>)));
connect(serverSocket, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(onModeChanged(QSslSocket::SslMode)));
connect(serverSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
QSslConfiguration sslConfiguration = serverSocket->sslConfiguration();
// ...
QSslCertificate cert(&certFile, QSsl::Pem);
QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem);
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
sslConfiguration.setLocalCertificate(cert); // set domain cert
sslConfiguration.setPrivateKey(key); // set domain key
sslConfiguration.setProtocol(QSsl::AnyProtocol);
// ...
QSslCertificate caCert(&caCertFile, QSsl::Pem);
sslConfiguration.setCaCertificates(QList<QSslCertificate>() << caCert); // add ca cert
serverSocket->setSslConfiguration(sslConfiguration);
serverSocket->startServerEncryption();
} else {
qDebug() << "Cannot set socket descriptor";
delete serverSocket;
}
}
void SslProxyServer::onEncrypted()
{
qDebug() << "onEncrypted";
}
void SslProxyServer::onReadyRead()
{
qDebug() << "onReadyRead";
}
void SslProxyServer::onSslErrors(QList<QSslError> sslErrors)
{
qDebug() << "onSslErrors";
}
void SslProxyServer::onModeChanged(QSslSocket::SslMode sslMode)
{
qDebug() << "onModeChanged(" << (int) sslMode << ")";
}
void SslProxyServer::onStateChanged(QAbstractSocket::SocketState socketState)
{
qDebug() << "onStateChanged(" << (int) socketState << ")";
}
void SslProxyServer::onError(QAbstractSocket::SocketError socketError)
{
qDebug() << "onError(" << (int) socketError << ")";
QSslSocket *serverSocket = qobject_cast<QSslSocket *>(sender());
qDebug() << serverSocket->errorString();
}
I've generated CA self-signed certificate with private key, and another certificate for specific domain, which I signed with my CA certificate. After I copy CA certificate to /usr/local/share/ca-certificates and run sudo update-ca-certificates. But when I try to connect to my proxy server using 3rd-party app, where my server used as https proxy I get QAbstractSocket::SslHandshakeFailedError error with next output:
Listening port 8888
incomingConnection
onModeChanged( 2 )
onError( 13 )
"Error during SSL handshake: error:1407609B:SSL routines:SSL23_GET_CLIENT_HELLO:https proxy request"
onStateChanged( 0 )
So it does not even enter in onReadyRead slot.
When I try to test my server using openssl command: openssl s_client -connect 127.0.0.1:8888 -debug - it is successfully connected to my server. Output contains next lines:
verify error:num=19:self signed certificate in certificate chain
verify return:0
No client certificate CA names sent
---
SSL handshake has read 2667 bytes and written 439 bytes
Verify return code: 19 (self signed certificate in certificate chain)
---
but I can send data to my server and see its raw value in my onReadyRead slot.
Some info about my env:
OS: Ubuntu 12.04 x86_64
Qt: 5.2.1 (GCC 4.6.1, 64 bits)
Thanks in advance,
... when I try to connect to my proxy server using 3rd-party app, where my server used as https proxy
... When I try to test my server using openssl command: openssl s_client -connect 127.0.0.1:8888 -debug - it is successfully connected to my server.
These are different things. With your openssl command you establish a TCP connection which you immediately upgrade to SSL. But, an https proxy works differently: it first establishes a TCP connection, then issues a HTTP CONNECT command and only once it gets a successful response from the proxy it upgrades the connection to SSL, e.g.
- client to server
> CONNECT ip:port HTTP/1.0\r\n
> \r\n
- followed by server to client
< HTTP/1.0 200 connection established\r\n
< \r\n
... SSL handshake ...
And because the client send a https proxy request like it should but you expect the immediate start of the SSL handshake (that is you expect a ClientHello message) this fails with:
"Error during SSL handshake: error:1407609B:SSL routines:SSL23_GET_CLIENT_HELLO:https proxy request"

QSslSocket proxy server (https) and certs. Handshake error

I'm writing a proxy server, http part is ready, but are having problems with https.
I created a certificate and private key (as I understood, without it will not work) in this way:
OpenSSL> req-x509-newkey rsa: 2048-keyout server.key-nodes-days 365-out server.csr
I did a simple QTcpServer that is passed a socketDescriptor to the created object on newIncomingConnection().
In constructor of my object I did:
sock = new QSslSocket();
connect (sock,SIGNAL(readyRead()),this,SLOT(onQuery()));
connect(sock,SIGNAL(disconnected()),this,SLOT(deleteLater()));
connect(sock,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError(QAbstractSocket::SocketError)));
connect(sock,SIGNAL(sslErrors(QList<QSslError>)),this,SLOT(sltSslErrors(QList<QSslError>)));
...
Load key and cert
...
sock->setProtocol(QSsl::AnyProtocol);
QSslKey sslKey(key, QSsl::Rsa);
QSslCertificate sslCert(cert);
sock->setPrivateKey(sslKey);
sock->setLocalCertificate(sslCert);
sock->setSocketDescriptor(socketDesc);
sock->startServerEncryption();
if(!sock->waitForEncrypted(30000)) {
qDebug()<<"wait for encrypted failed";
}
On connect in console I see "wait for encrypted failed" and socket emited signal error() with QAbstractSocket::SslHandshakeFailedError.
Could you give advice on what else to do that would be to establish the ssl connection without error ?
I believe you need to call setSocketDescriptor before calling the setPrivateKey and setLocalCertificate methods.
Below is code that I've used to create a HTTPS Server Socket, extending QTcpServer.
void SslServer::incomingConnection(qintptr socketDescriptor)
{
QSslSocket *serverSocket = new QSslSocket;
if (serverSocket->setSocketDescriptor(socketDescriptor)) {
QFile keyFile(<sslKeyFileName>);
if (!keyFile.open(QIODevice::ReadOnly)) {
delete serverSocket;
return;
}
QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
if (key.isNull()) {
delete serverSocket;
return;
}
keyFile.close();
serverSocket->setPrivateKey(key);
// to prevent asking for client certificate.
serverSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
serverSocket->setLocalCertificate(<certificateFileName>);
serverSocket->startServerEncryption();
if (serverSocket->waitForEncrypted(3000)) {
// this will emit a newConnection() signal
addPendingConnection(serverSocket);
} else {
qDebug() << "Encryption Failed.";
delete serverSocket;
}
} else {
delete serverSocket;
}
}