QTcpSocket有时不发送数据

时间:2012-03-15 06:25:59

标签: qt

我有两个QT应用。一个应用程序可以被认为持有大数据,它每秒向第二个应用程序发送大约10 KB的数据块。

之前我曾尝试使用QUdpSocket传输数据但由于MTU限制约2-5K并需要自行分割和重新组合数据,我切换到QTcpSocket。

有时使用QTcpSocket正确发送数据(特别是如果我每隔100毫秒非常频繁地写数据),但有时根本不会发送数据。 5秒后甚至没有。有时,几个数据块在内部缓冲很长一段时间(几秒钟),然后一起发送。

m_socket = new QTcpSocket(this);
m_socket->connectToHost(QHostAddress::LocalHost, 45454);

sendDataEverySec()
{
    QByteArray datagram(10000, 'a');
    qint64 len = m_socket->write(datagram);
    if(len != datagram.size())
           qDebug() << "Error"; //this NEVER occurs in MY case.
    m_socket->flush();
}

在接收方,我使用readyRead信号来知道数据何时到达。

如何确保立即发送数据?对于我想做的事情,还有更好的选择吗?

编辑::当我在1秒的长间隙后写字时,每次发送方发送数据时,我会在接收方收到"QAbstractSocket::SocketTimeoutError"。如果发件人频繁写入数据,则不会收到此错误 是否可以使用QTcpSocket以我正在做的方式传输数据????

编辑2:在接收方,当发出readyRead信号时,我再次检查while(m_socket->waitForReadyRead(500)),因此我得到"QAbstractSocket::SocketTimeoutError"。此外,此检查阻止了单个块的传送 完成更多文档后,似乎readyRead会在新数据可用时不断发出,因此无需waitForReadyRead
我收到了所有已发送的数据,但数据仍未立即生效。有时会合并两到三个块。这可能是因为接收方在读取数据等方面的延迟。

2 个答案:

答案 0 :(得分:2)

在接收方,当发出readyRead信号时,我再次检查while(m_socket->waitForReadyRead(500)),因此我得到"QAbstractSocket::SocketTimeoutError"。此外,此检查阻止了单个块的传送。

在浏览了更多文档之后,似乎readyRead将在新数据可用时不断发出,因此不需要waitForReadyRead。 它解决了我的问题。

答案 1 :(得分:0)

我的客户端服务器应用程序的典型解决方案。

在服务器端:

class Server: public QTcpServer {

public:
    Server(QObject *parent = 0);
    ~Server();
private slots:
    void readyRead();
    void disconnected();
protected:
    void incomingConnection(int);

};

on cpp:

void Server::incomingConnection(int socketfd) {

    QTcpSocket *client = new QTcpSocket(this);
    client->setSocketDescriptor(socketfd);


    connect(client, SIGNAL(readyRead()), this, SLOT(readyRead()));
    connect(client, SIGNAL(disconnected()), this, SLOT(disconnected()));
}

void Server::disconnected() {
    QTcpSocket *client = (QTcpSocket*) sender();

    qDebug() << " INFO : " << QDateTime::currentDateTime()
            << " : CLIENT DISCONNECTED " << client->peerAddress().toString();
}

void Server::readyRead() {
    QTcpSocket *client = (QTcpSocket*) sender();

    while (client->canReadLine()) {
              //here i needed a string..
        QString line = QString::fromUtf8(client->readLine()).trimmed(); 
    }
}

在客户端:

class Client:public QTcpSocket {

public:
    Client(const QHostAddress&, int, QObject* = 0);
    ~Client();
    void Client::sendMessage(const QString& );
private slots:
    void readyRead();
    void connected();
public slots:
    void doConnect();
};

on cpp:

void Client::readyRead() {

    // if you need to read the answer of server..
    while (this->canReadLine()) {
    }
}

void Client::doConnect() {
    this->connectToHost(ip_, port_);
    qDebug() << " INFO : " << QDateTime::currentDateTime()
            << " : CONNESSIONE...";
}

void Client::connected() {
    qDebug() << " INFO : " << QDateTime::currentDateTime() << " : CONNESSO a "
            << ip_ << " e PORTA " << port_;
    //do stuff if you need
}


void Client::sendMessage(const QString& message) {
    this->write(message.toUtf8());
    this->write("\n"); //every message ends with a new line
}