1
#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

4 回答 4

1

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

QT       += core network
于 2012-08-10T06:53:19.377 回答
1

您需要将您的课程添加到 .pro 文件中

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

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

于 2012-05-25T12:24:51.450 回答
1

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

#include "foo.moc"

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

#includeQt 标头的行中也有问题。我发现以下工作:

#include <QtCore/QCoreApplication>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
于 2012-06-01T07:03:25.737 回答
0

两件事情:

1)您应该公开从 QObject 派生。

2)你是在moc'ing这个文件然后编译和链接输出吗?如果你包含 Q_OBJECT 宏并且不 moc,你会得到这样的错误。

于 2012-05-14T03:58:50.973 回答