如何解决Qtcp在服务器和客户端之间以自定义速率发送数据
我正在做这个项目
一个简单的服务器/客户端应用程序:
-
哪个服务器以自定义速率(数据/秒)发送数据(一些字符串...)
-
客户端控制速率(可以改变速率)
-
客户端计算服务器发送的数据速率并与提交的速率进行比较
我做了简单的 TCP 服务器客户端聊天
问题来了:
-
如何以自定义速率发送数据? 比如:100个字符串,100个单词……
-
应该如何让服务器知道速率改变了?
-
客户如何计算费率?
服务器:
#include "widget.h"
#include "ui_widget.h"
#include <QtWidgets/QMessageBox>
#include <QTime>
Widget::Widget(QWidget *parent) :
QWidget(parent),ui(new Ui::Widget)
{
ui->setupUi(this);
ui->lineEdit_Port->setText("5003");
ui->pushButton_Send->setEnabled(false);
m_server = new QTcpserver();
connect(m_server,&QTcpserver::newConnection,this,&Widget::server_New_Connect);
}
Widget::~Widget()
{
m_server->close();
m_server->deleteLater();
delete ui;
}
void Widget::server_New_Connect()
{
//Get client connection
m_socket = m_server->nextPendingConnection();
QObject::connect(m_socket,&QTcpsocket::readyRead,&Widget::socket_Recv_Data);
QObject::connect(m_socket,&QTcpsocket::disconnected,&Widget::socket_disconnect);
ui->textbrowser->setTextColor(Qt::green);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",10));
ui->textbrowser->append(tr("Client Connected!%1\n").arg(QTime::currentTime().toString()));
ui->pushButton_Send->setEnabled(true);
}
void Widget:: socket_Recv_Data()
{
QByteArray data_tmp;
data_tmp = m_socket->readAll();
if(!data_tmp.isEmpty())
{
QString str = QString(data_tmp);
ui->textbrowser->setTextColor(Qt::gray);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",10));
ui->textbrowser->append("From Client: "+QTime::currentTime().toString());
ui->textbrowser->setTextColor(Qt::blue);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",13));
ui->textbrowser->append(str);
QTextCursor cursor = ui->textbrowser->textCursor(); //Automatically drop to the bottom
cursor.movePosition(QTextCursor::End);
ui->textbrowser->setTextCursor(cursor);
}
}
void Widget:: socket_disconnect()
{
ui->pushButton_Send->setEnabled(false);
ui->textbrowser->setTextColor(Qt::gray);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",10));
ui->textbrowser->append(tr("Client disconnected !%1\n").arg(QTime::currentTime().toString()));
}
void Widget::on_pushButton_Listen_clicked()
{
if (ui->pushButton_Listen->text() ==QString("start server"))
{
qint16 port = ui->lineEdit_Port->text().toInt();
if(!m_server->listen(QHostAddress::Any,port))
{
QMessageBox::critical(this,"Error!",m_server->errorString(),QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes );
return;
}
ui->pushButton_Listen->setText("stop server");
}
else
{
if(m_socket->state() == QAbstractSocket::ConnectedState)
{
m_socket->disconnectFromHost();
}
m_server->close();
ui->pushButton_Listen->setText("start server");
ui->pushButton_Send->setEnabled(false);
}
}
void Widget::on_pushButton_Send_clicked()
{
if (ui->textEdit->toPlainText() == QString())
{
QMessageBox msgb;
msgb.setText("Cannot send empty message !");
msgb.resize(60,40);
msgb.exec();
return;
}
m_socket->write(ui->textEdit->toPlainText().toUtf8());
ui->textbrowser->setTextColor(Qt::gray);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",10));
ui->textbrowser->append("From Server: "+QTime::currentTime().toString());
ui->textbrowser->setTextColor(Qt::red);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",16));
ui->textbrowser->append(ui->textEdit->toPlainText().toUtf8());
m_socket->flush();
ui->textEdit->clear();
}
客户:
#include "widget.h"
#include "ui_widget.h"
#include <QtWidgets/QMessageBox>
#include <QTime>
Widget::Widget(QWidget *parent) :
QWidget(parent),ui(new Ui::Widget)
{
ui->setupUi(this);
m_socket=new QTcpsocket();
QObject::connect(m_socket,&Widget::sockt_recv_data);
QObject::connect(m_socket,&Widget::socket_disconnect);
ui->pushButton_Send->setShortcut(QKeySequence(tr("ctrl+return")));
ui->lineEdit_IP->setText("127.0.0.1");
ui->lineEdit_Port->setText("5003");
ui->pushButton_Send->setEnabled(false);
}
Widget::~Widget()
{
delete m_socket;
delete ui;
}
void Widget::on_pushButton_Connect_clicked() //Connect button
{
QString IP;
qint16 port;
if (ui->pushButton_Connect->text() == QString("Connect"))
{
IP=ui->lineEdit_IP->text();
port=ui->lineEdit_Port->text().toInt();
m_socket->abort();
m_socket->connectToHost(IP,port);
if (!m_socket->waitForConnected())
{
QMessageBox msgBox;
msgBox.setText("Connection timed out!");
msgBox.resize(40,30);
msgBox.exec();
return;
}
QMessageBox msgBox;
msgBox.setText("Connection succeeded!");
msgBox.resize(40,30);
msgBox.exec();
ui->pushButton_Send->setEnabled(true);
ui->pushButton_Connect->setText("disconnect");
}
else
{
m_socket->disconnectFromHost();
ui->pushButton_Connect->setText("Connect");
ui->pushButton_Send->setEnabled(false);
}
}
void Widget::on_pushButton_Send_clicked() //Send button
{
if (ui->textEdit->toPlainText()== QString()) //Empty message detection
{
QMessageBox msgb;
msgb.setText("Cannot send empty messages!");
msgb.resize(60,40);
msgb.exec();
return;
}
ui->textbrowser->setTextColor(Qt::gray);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",10));
ui->textbrowser->append("From Client: "+QTime::currentTime().toString());
ui->textbrowser->setTextColor(Qt::blue);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",16));
ui->textbrowser->append(ui->textEdit->toPlainText().toUtf8());
m_socket->write(ui->textEdit->toPlainText().toUtf8());
m_socket->flush();
ui->textEdit->clear();
}
void Widget:: sockt_recv_data()
{
QByteArray data_tmp;
data_tmp = m_socket->readAll();
if (!data_tmp.isEmpty())
{
//QString str = ui->textbrowser->toPlainText();
QString str=QString(data_tmp);
ui->textbrowser->setTextColor(Qt::gray);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",10));
ui->textbrowser->append("From Server: "+QTime::currentTime().toString());
ui->textbrowser->setTextColor(Qt::red);
ui->textbrowser->setCurrentFont(QFont("Times New Roman",13));
ui->textbrowser->append(str);
}
}
void Widget:: socket_disconnect()
{
ui->pushButton_Send->setEnabled(false);
ui->pushButton_Connect->setText("Connect");
QMessageBox msgBox;
msgBox.setText("disconnect");
msgBox.resize(40,30);
msgBox.exec();
}
解决方法
你可以试试这样的:
这里我使用 QJsonDocument 发送,我认为更容易操作。该函数发送数组的确切大小。我出了点问题,write_socket_retry 被调用重试。
void multisocket::write_socket(const QJsonObject &obj)
{
QJsonDocument doc(obj);
QByteArray array(doc.toJson());
qint32 size = array.size();
QByteArray total = IntToArray(size);
socket->write(total);
qint64 writed = socket->write(array);
if(writed == size){
QString str = QString("Socket sent packet: %3 size %1 - Socket descriptor: %2")
.arg(QString::number(size))
.arg(QString::number(socket->socketDescriptor()))
.arg(writed > 0);
qDebug() << str;
total_sent = 0;
} else {
socket->abort();
QTimer::singleShot(3000,[this,obj](){
write_socket_retry(obj);
});
}
}
void multisocket::write_socket_retry(const QJsonObject &obj){
if(total_sent >= 10){
QString str = QString("Socket fail - Socket descriptor: %1 ")
.arg(QString::number(socket->socketDescriptor()));
qDebug() << str;
total_sent = 0;
} else {
QString str = QString("Socket fail - Socket descriptor: %1 ")
.arg(QString::number(socket->socketDescriptor()));
qDebug() << str;
total_sent++;
write_socket(obj);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。