简体   繁体   中英

Problems with Qt/C++ echo client + python echo server (no data received)

I'm using this simple echo server in python: http://ilab.cs.byu.edu/python/socket/echoserver.html It works with the client in python but I can't get it to wotk with my client written in Qt/C++. They successfully establish connection bu there is no data being sent between them. I was able to make my client sent data (for some reason it required forcibly flushing socket after every write) but it still doesn't receive any messages from server. No readyRead() is being fired and bytesAvailable is 0.

#include <QDataStream>
#include <QTextStream>
#include <QDebug>
#include "echoclient.h"

EchoClient::EchoClient(QObject *parent) : QObject(parent), serverSocket(new QTcpSocket(this)), networkSession(nullptr)
{
    connect(serverSocket, &QTcpSocket::readyRead, this, &printEcho);
    connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(displayError(QAbstractSocket::SocketError)));
    connect(serverSocket, &QTcpSocket::connected,
            this, [this](){QTextStream(stdout) << "Connection established" << endl; messageLoop();});
    connect(serverSocket, QTcpSocket::disconnected, this, &disconnect);
}

void EchoClient::connectToServer()
{
    serverSocket->connectToHost(serverIP, serverPort);
}

void EchoClient::setIP(const QString &ip)
{
    serverIP = ip;
}

void EchoClient::setPort(quint16 port)
{
    serverPort = port;
}

void EchoClient::sendMessage(const QString &msg)
{
    qDebug() << serverSocket->write(msg.toUtf8());
    qDebug() << serverSocket->isOpen(); // true
    qDebug() << serverSocket->flush(); // true, why do I need it? It should be working without it
    qDebug() << "bytes available: " << serverSocket->bytesAvailable();
}

void EchoClient::disconnect()
{
    QTextStream(stdout) << "Disconnected" << endl;
}

void EchoClient::printEcho() const
{
    QDataStream in(serverSocket);
    in.setVersion(QDataStream::Qt_5_5);
    QString echoMsg;
    in >> echoMsg;
    QTextStream(stdout) << "Echo: " << echoMsg << endl;
}

void EchoClient::displayError(QAbstractSocket::SocketError) const
{
    qDebug("error occured");
}

void EchoClient::messageLoop()
{
    QTextStream(stdout) << "You can enter messages now" << endl;
    QTextStream conin(stdin);
    while (true) {
        QString msg;
        conin >> msg;
        sendMessage(msg);
    }
}

Try debug it using tcpdump -i lo port $serverport or similar. What if you remove flush() function frome the code, and listen on that port with nc -l $serverport (or whatever you use) and try sending some data back to client?

Upd: it's ok if you get

bytesAvailable is 0

You calling it right after sending a message. You should call it in void EchoClient::printEcho() const method.

The problem was with me forgetting how Qt works. Here:

connect(serverSocket, &QTcpSocket::connected,
            this, [this](){QTextStream(stdout) << "Connection established" << endl; messageLoop();});

I called messageLoop() at the end of the slot. Which loops. Indefinitely. So the control is never returned to Qt's EventLoop and new signals can't be processed. I might've thought that any new incoming signals would magically interrupt already running program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM