StAx
StAx

Reputation: 272

Read data from mirth connect - tcp server qt creator

im stuck with this problem, just i need read the message sent from mirth connect (normal text or hl7) to recieve in the software and write the message in data base, this is my TCPServer Code:

MyServer::MyServer(QObject *parent):
QObject(parent)
{
server = new QTcpServer(this);

connect(server,SIGNAL(newConnection()),this,SLOT(newConnection()));

if(!server->listen(QHostAddress::Any,1234))
{

   qDebug() << "Server not start!";
}
else
{
   qDebug() << "Server started";
}
}

 void MyServer::newConnection()
{
QTcpSocket *socket = server->nextPendingConnection();
qDebug() << "Client agree";
QString data = QTextCodec::codecForMib(1015)->toUnicode(socket->readAll());

qDebug() << socket->readAll();
socket->flush();
socket->waitForBytesWritten(3000);
socket->close();

}

I think the problem is socket->readAll(); but this line take all the bytes sent from the client and write in console and show nothing, somebody can help me pls?

Upvotes: 0

Views: 791

Answers (2)

Orest Hera
Orest Hera

Reputation: 6786

You should think about a network connection as about a process that has various phases: connecting, payload transfer, closing. Network information is transferred using packets of limited size. Time interval between packets is large enough in scale of CPU clock. It is even possible to have significant timeouts. So, to use CPU for other tasks between packets, networking functions are triggered by events.

The signal QTcpServer::newConnection() means that a TCP connection is just established (only few packets were exchanged to start). So, nothing can be read from QTcpSocket. It is just the beginning.

From that point you should work with pointer to QTcpSocket. It can be handled either

  • asynchronously (handle an even and exit from handler to allow dispatching of other evens in that thread that is mandatory in case of GUI thread to keep UI in responsive state) or
  • synchronously (here the thread is in sleep state between packets).

You can find useful examples in the documentation of QAbstractSocket that is a base class of QTcpSocket.

The simpler blocking connection:

int numRead = 0, numReadTotal = 0;
char buffer[50];

forever {
    numRead  = socket->read(buffer, 50);

    // do whatever with array

    numReadTotal += numRead;
    if (numRead == 0 && !socket->waitForReadyRead())
        break;
}

There are also various signals that are triggered for specific events. For example QAbstractSocket::readyRead() is triggered when some new data is available. So, asynchronous usage:

// This slot is connected to QAbstractSocket::readyRead()
void MyServer::readyReadSlot()
{
    QByteArray data = socket->readAll();
    ....
}

There are also signals as QAbstractSocket::disconnected(), QAbstractSocket::error(). When socket is disconnected it is useful to delete it by delayed socket->deleteLater() called from disconnected socket handler.

It is needed to be careful with asynchrous solution, since it is possible to have simultaneously many connections. So, many different instances of QTcpSocket should be managed.

Upvotes: 2

allyusd
allyusd

Reputation: 365

You need wait socket readyRead signal before readAll.

This is a simple example for tcpserver

m_server = new QTcpServer();

connect(m_server, &QTcpServer::newConnection, [=]() {
    qDebug() << "new client socket";

    QTcpSocket* socket = this->m_server->nextPendingConnection();

    connect(socket, &QTcpSocket::disconnected, [=]() {
        qDebug() << "client socket disconnected";

        socket->deleteLater();
    });

    connect(socket, &QTcpSocket::readyRead, [=]() {
        qDebug() << "client readyRead";

        QString string = socket->readAll();
        qDebug() << "Read: " << string;
        string = string.toUpper();
        qDebug() << "Send " << string;

        socket->write(string.toLatin1());
        socket->close();
    });
});

m_server->listen(QHostAddress::Any, 8811);
qDebug() << "server listen";

Upvotes: 1

Related Questions