了解全部信息,请关注专栏:
优化服务器
1.不能设置随拖动变大:
this->setLayout(ui->verticalLayout);
2. 未连接就能发送消息:
//在处理新连接槽函数中加入
if(!ui->btnSend->isEnabled()){//只有客户端连接上之后才能向发送数据
ui->btnSend->setEnabled(true);
}
//在构造和端口连接/停止监听中加入
ui->btnSend->setEnabled(false);
3. 设置光标位置最下
在读取数据的信号处理函数
ui->textEditRev->moveCursor(QTextCursor::End);
ui->textEditRev->ensureCursorVisible();
4. 防止无客户端接入时候发送 --> 造成访问越界
在发送槽函数中添加
if(tcpClients.isEmpty()){ //客户端数组为空,没有发送对象
QMessageBox msgBox;
msgBox.setWindowTitle("发送失败");
msgBox.setText("没有客户端接入!");
msgBox.exec();
return;
}
5. 实现comboBoxChildren 的快速度刷新
-->添加后马上刷新上去,断开连接后马上删除
在处理新连接的函数中添加:
//当有新的连接接入的时候,刷新comboBox上的内容
ui->comboBoxChildren->addItem(QString::number(connection->peerPort()));//添加新的连接
ui->comboBoxChildren->setCurrentText(QString::number(connection->peerPort()));//将新的连接显示未当前连接
//在端口连接信号处理函数中添加
//根据当前端口号找到对应的索引
int tmpIndex =ui->comboBoxChildren->findText(QString::number(tmpSock->peerPort()));
ui->comboBoxChildren->removeItem(tmpIndex); //根据索引删除comboBox上的条目
if(ui->comboBoxChildren->count() == 0) //当没有客户端接入得到时候让发送按钮不可选
ui->btnSend->setEnabled(false);
6.优化下标管理:
//在btnSend进行修改通过名字匹配当前客户端:
if(ui->comboBoxChildren->currentText() != "all"){ //选单独一个客户端发送
QString currentName = ui->comboBoxChildren->currentText();//拿到当前客户端对应的名字
for(QTcpSocket *tmp:tcpClients){//遍历客户端数组
if(QString::number(tmp->peerPort())==currentName)//当客户端名字匹配才发送
tmp->write(ui->textEditSend->toPlainText().toStdString().c_str());}
// 通过全局的childIndex 匹配用户选择的客户端进行数据发送
//tcpClients[childIndex]->write(ui->textEditSend->toPlainText().toStdString().c_str());
}
================================================
客户端优化:
细节: 信号与槽中不能带参数-->否则不起作用
连接判断优化
ip地址不同的时候也会显示连接成功 --> 之前的判断链接中也加入了 -- 不合理
连接按钮槽函数
绑定信号与槽,进行 超时判断和 连接处理 和 错误处理
还包括定时器的初始化
void Widget::on_btnConnect_2_clicked()
{
qDebug()<<"connecting";
// 读取客户端输入的ip 和 端口号进行连接
client->connectToHost(ui->lineEditIpAddr->text(),ui->lineEditPort->text().toUInt());
//设置定时器 -> 进行超时判断:
timer = new QTimer(this);
timer->setSingleShot(true); //这个定时器只会被触发一次
timer->setInterval(5000); //5000ms - 5s
//绑定信号与槽,处理定时器超时
connect(timer,SIGNAL(timeout()),this,SLOT(onTimeOut()));
// 绑定信号与槽,进行连接判断
connect(client,SIGNAL(connected()),this,SLOT(onConnected()));
//进行错误处理 --> 比如
connect(client,SIGNAL(error(QAbstractSocket::SocketError)),
this,SLOT(onError(QAbstractSocket::SocketError)));
//当连接被按下的时候,避免重复按下 --> 让整个窗口不可用
this ->setEnabled(false);
timer->start(); // 启动定时器
}
连接处理槽函数
// 信号与槽处理连接状态
void Widget::onConnected()
{
timer->stop(); //连接成功 --> 不超时-->定时器停止
this->setEnabled(true); //连接成功后让窗口可用
ui->textEditRev->append("连接成功!"); //在文本框内给出连接提示
//设置控件状态
ui->btnConnect_2->setEnabled(false);
ui->lineEditPort->setEnabled(false);
ui->lineEditIpAddr->setEnabled(false);
ui->btnDisconnect->setEnabled(true);
ui->btnSend->setEnabled(true);
}
连接错误处理槽函数
void Widget::onError(QAbstractSocket::SocketError error)
{
qDebug()<<"连接错误"<<error;
ui->textEditRev->insertPlainText("连接出错:"+client->errorString());
this->setEnabled(true); //连接超时,,让窗口可用
on_btnDisconnect_clicked(); // 终止连接
}
连接超时处理槽函数
void Widget::onTimeOut()
{
ui->textEditRev->insertPlainText("连接超时");
client->abort(); //放弃当前连接
this->setEnabled(true); //连接超时,,让窗口可用
}
效果演示:
设置正确的ip -->连接成功
设置错误的ip ->定时器计时5s,没连接上就是超时
连接超时