QT中的低TCP连接性能问题

时间:2019-01-16 15:39:51

标签: c++ qt sockets tcp

我正在一个图像处理项目中,我从相机中获取帧,并通过Qt库内置的TCP连接发送帧。 我尝试发送24帧,但是运行程序时(大约)只有13帧。

我使用信号和插槽开始与按钮的连接,当连接建立时,计时器开始计时,我每秒发送24帧。

编辑:我切换到单连接服务器,但对性能没有太大影响,有时帧会损坏(?)(我只看到空白帧)

tcpsender.cpp

#include "tcpsender.h"
#include "ui_tcpsender.h"

#include <QtWidgets>
#include <QtNetwork>
#include <QtCore>
#include <QDebug>
#include <QBuffer>
#include <QDataStream>

#define XRES 640
#define YRES 480


TCPSender::TCPSender(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TCPSender)
{
    ui->setupUi(this);
    statusLabel = new QLabel(tr("Ready to send frames on port 6667"));
    statusLabel->setWordWrap(true);
    startButton = new QPushButton(tr("&Start"));
    auto quitButton = new QPushButton(tr("&Quit"));
    auto buttonBox = new QDialogButtonBox;
    buttonBox->addButton(startButton, QDialogButtonBox::ActionRole);
    buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);

    socket = new QTcpSocket(this);
    connect(startButton, &QPushButton::clicked, this, &TCPSender::startConnection);
    connect(quitButton, &QPushButton::clicked, this, &TCPSender::close);
    connect(socket, SIGNAL(connected()), SLOT(startSending()));
    connect(&timer, &QTimer::timeout, this, &TCPSender::sendFrame);

    auto mainLayout = new QVBoxLayout;
    mainLayout->addWidget(statusLabel);
    mainLayout->addWidget(buttonBox);
    setLayout(mainLayout);

    setWindowTitle(tr("Broadcast Sender"));
    camera = new Camera("/dev/video0", XRES, YRES);

    time = QTime::currentTime();

}

TCPSender::~TCPSender()
{
    delete ui;
}

bool TCPSender::startConnection()
{
    if (socket->state() == QAbstractSocket::UnconnectedState)
    {

        socket->connectToHost(ui->lineEdit->text(), 6667, QIODevice::WriteOnly);
        return socket->waitForConnected();

    }
}

void TCPSender::startSending()
{
    startButton->setEnabled(false);
    timer.start(1000/24);
    qDebug()<<"Timer start";
}

bool TCPSender::sendFrame()
{
    if(socket->state()==QAbstractSocket::ConnectedState){
        auto frame = camera->frame();

        image = new QImage(frame.data,XRES,YRES,QImage::Format_RGB888);
        QImage im = image->convertToFormat(QImage::Format_Grayscale8);
        QByteArray ba;
        QBuffer buffer(&ba);
        im.save(&buffer,"BMP");

        qDebug()<<"writing socket";
        socket->write(ba);

        int speed = time.msecsTo(QTime::currentTime());
        time = QTime::currentTime();
        speed = 1000*300/speed;
        ui->label->setText(QString("%1 kb/s").arg(speed));
        delete image;

   }

}

receiver.cpp

#include "reciever.h"    
#include <QBuffer>
#include <QTcpSocket>
#include <QImage>
#include <QDebug>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <unistd.h>

Reciever::Reciever(QObject* parent): QTcpServer(parent)
{
    connect(this, SIGNAL(newConnection()), this, SLOT(addConnection()));
}

void Reciever::addConnection()
{
    qDebug()<<"Adding Connection";
    QTcpSocket* connection = nextPendingConnection();
    connect(connection, SIGNAL(readyRead()),
            this, SLOT(receiveImage()));

    connections.append(connection);
    QBuffer* buffer = new QBuffer(this);
    buffer->open(QIODevice::ReadWrite);
    buffers.insert(connection, buffer);

}

void Reciever::receiveImage()
{
    qDebug()<<"RECIEVE";
    QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
    QBuffer* buffer = buffers.value(socket);
    qint64 bytes = buffer->write(socket->readAll());   
    emit sendBuffer(buffer,bytes);
}

1 个答案:

答案 0 :(得分:1)

您在每个计时器滴答时都在呼叫startConnection();。这具有在关闭和重新打开连接之间交替的作用。

  • 您可以在startConnection中删除对sendFrame的调用,保持TCP连接打开。

  • 或者您将计时器的滴答频率加倍至timer.start(1000/48);