====== 11. QT - TCP/IP komunikace ====== Program napsaný pomocí knihoven v QT ukazuje, jak vytvořit jednoduché spojení a vyměnit si mezi serverem a klientem TCP/IP zprávu. ===== Server ===== Serverová část je vytvořena instancí třídy [[https://doc.qt.io/qt-5/qtcpserver.html|QTcpServer]]. Vytvořený objekt poslouchá metodou [[https://doc.qt.io/qt-5/qtcpserver.html#listen|QTcpServer::listen()]] na specifikovaném portu, při praktickém nasazení je třeba dbát na to, aby nebyl zvolený port v konfliktu s některým ze [[https://cs.wikipedia.org/wiki/Seznam_%C4%8D%C3%ADsel_port%C5%AF_TCP_a_UDP|standardně využívaných]]. Při příchozím spojení je emitován signál [[https://doc.qt.io/qt-5/qtcpserver.html#newConnection|QTcpServer::newConnection()]], který je propojen s místní metodou. Server::Server (QObject *parent) : QObject(parent) { server = new QTcpServer (this); // cekame na spojeni z libovolne IP adresy na portu 1234 if (!server->listen (QHostAddress::Any, 1234)) qDebug() << "nepodarilo se zahajit poslouchani na portu 1234"; // propojeni signalu newConnection se slotem, ktery zpracuje prichozi spojeni connect (server, SIGNAL(newConnection()), this, SLOT(handleConnection())); } Příchozí spojení otevře nový [[https://cs.wikipedia.org/wiki/S%C3%AD%C5%A5ov%C3%BD_socket|síťový socket]]. Z praktických důvodů je dobré počkat, dokud nezačne klient posílat data (resp. dokud se tato data neobjeví ve vstupním bufferu) - k tomu slouží metoda [[https://doc.qt.io/qt-5/qabstractsocket.html#waitForReadyRead|QAbstractSocket::waitForReadyRead]]. void Server::handleConnection() { socket = server->nextPendingConnection(); while(!(socket->waitForReadyRead(100))); QByteArray data = socket->readAll(); qDebug() << data; socket->write("ACK"); connect (socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); socket->disconnectFromHost(); } Pokud by zůstal socket obsazen, nebude možné znova spustit aplikaci. Server::~Server() { socket->close(); } ===== Klient ===== Client::Client (QString message, QObject *parent) : QObject(parent) { socket = new QTcpSocket (this); // 127.0.0.1 socket->connectToHost ("localhost", 1234); socket->write(message.toLocal8Bit()); socket->flush(); connect (socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); connect (socket, SIGNAL(readyRead()), this, SLOT(readData())); } void Client::readData() { // precteme data ze serveru qDebug() << socket->readAll(); } Client::~Client() { socket->close(); }