gsrunion
gsrunion

Reputation: 409

Simple QT console TCP application. What am I doing wrong?

#include <QtCore/QCoreApplication>
#include <QTCore>
#include <QtNetwork>
#include <QDebug>

#define CONNECT(sndr, sig, rcvr, slt) connect(sndr, SIGNAL(sig), rcvr, SLOT(slt))

class mynet : QObject
{
    Q_OBJECT

public:
    mynet()
    {}

    void start()
    {
        CONNECT(tcpServer,       newConnection(),                     this, acceptConnection());
        CONNECT(tcpClient,       connected(),                         this, startTransfer());
        CONNECT(tcpClient,       bytesWritten(qint64),                this, updateClientProgress(qint64));
        CONNECT(tcpClient,       error(QAbstractSocket::SocketError), this, displayError(QAbstractSocket::SocketError));

        // start server listening
        tcpServer->listen();
        while(!tcpServer->isListening());

        // make client connection
        tcpClient->connectToHost(QHostAddress::LocalHost, tcpServer->serverPort());
    }

public slots:
    void acceptConnection()
    {
        tcpServerConnection = tcpServer->nextPendingConnection();
        CONNECT(tcpServerConnection, readyRead(), this, updateServerProgress());
        CONNECT(tcpServerConnection, error(QAbstractSocket::SocketError), this, displayError(QAbstractSocket));
        tcpServer->close();
    }

    void startTransfer()
    {
        bytesToWrite = TotalBytes - (int)tcpClient->write(QByteArray(PayloadSize, '@'));
    }

    void updateServerProgress()
    {
        bytesReceived += (int)tcpServerConnection->bytesAvailable();
        tcpServerConnection->readAll();

        if (bytesReceived == TotalBytes)
        {
            qDebug() << "done";
            tcpServerConnection->close();
        }
    }

    void updateClientProgress(qint64 numBytes)
    {
        // callen when the TCP client has written some bytes
        bytesWritten += (int)numBytes;

        // only write more if not finished and when the Qt write buffer is below a certain size.
        if (bytesToWrite > 0 && tcpClient->bytesToWrite() <= 4*PayloadSize)
            bytesToWrite -= (int)tcpClient->write(QByteArray(qMin(bytesToWrite, PayloadSize), '@'));
    }

    void displayError(QAbstractSocket::SocketError socketError)
    {
        if (socketError == QTcpSocket::RemoteHostClosedError)
            return;

        qDebug() << tcpClient->errorString();


        tcpClient->close();
        tcpServer->close();
    }

private:
    QTcpServer* tcpServer;
    QTcpSocket* tcpClient;
    QTcpSocket* tcpServerConnection;
    int bytesToWrite;
    int bytesWritten;
    int bytesReceived;
    int TotalBytes;
    int PayloadSize;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    mynet m1;
    m1.start();

    return a.exec();
}

I get an

Undefined symbols for architecture x86_64:
"vtable for mynet", referenced from:
  mynet::mynet() in main.o
  mynet::~mynet()in main.o. 

Please advise what I am doing wrong. Can I not inline the method definitions in the class for some reason in Qt?

Upvotes: 1

Views: 2381

Answers (4)

Cameron Tinker
Cameron Tinker

Reputation: 9789

Make sure to add network to your .pro file. This will create the correct linking to the network library functions.

QT       += core network

Upvotes: 1

Assuming that your source file is named foo.cpp, you have to put the following line at the very end:

#include "foo.moc"

This line tells qmake and the VS Qt add-in that the file should be run via moc, and that the generated moc file should be named foo.moc.

You also have problems in the #include lines for Qt headers. I've found that the following work:

#include <QtCore/QCoreApplication>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>

Upvotes: 1

Julian
Julian

Reputation: 1542

You need to add your class to the .pro file

HEADERS += mynet.h
SOURCES += mynet.cpp

so the meta-object compiler can scan them and work out they need moc'ing and generate the relevant stubs.

Upvotes: 1

Dusty Campbell
Dusty Campbell

Reputation: 3156

Two things:

1) You should publicly derive from QObject.

2) Are you moc'ing this file and then compiling and linking the output? If you include the Q_OBJECT macro and don't moc, you will get an error like that.

Upvotes: 0

Related Questions