简单的QT控制台TCP应用程序。我究竟做错了什么?

时间:2012-05-14 01:50:31

标签: qt

#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();
}

我得到了

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

请告知我做错了什么。我是否可以出于某种原因在Qt中内联类中的方法定义?

4 个答案:

答案 0 :(得分:1)

您需要将您的班级添加到.pro文件

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

所以元对象编译器可以扫描它们并找出它们需要moc'ing并生成相关的存根。

答案 1 :(得分:1)

假设您的源文件名为foo.cpp,您必须将以下行放在最后

#include "foo.moc"

这一行告诉qmake和VS Qt加载项该文件应该通过moc运行,并且生成的moc文件应该命名为foo.moc。

Qt标题的#include行也有问题。我发现了以下工作:

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

答案 2 :(得分:1)

确保将网络添加到.pro文件中。这将创建与网络库函数的正确链接。

QT       += core network

答案 3 :(得分:0)

两件事:

1)你应该公开派生自QObject。

2)你是moc'ing这个文件,然后编译和链接输出?如果包含Q_OBJECT宏而不包含moc,则会出现类似的错误。

相关问题