用途:本来是用于给单片机收发消息的,只做了服务端,客户端是用别的网络调试助手测试。
展示
*不想看我逼逼的,源代码在这里:https://download.csdn.net/download/weixin_43387612/11943194
一、实现功能
- 显示客户端连接和客户端断开数量
- 给所有客户端发送文件,给单独选中的客户端发送文件(下拉框选择)
- 接收客户端发过来的指令(分别有进度条,下面16个io_in点亮,8个io_out)
**补充:**最右边最下面的RUN按键没有具体功能,目前是摆设
二、正文
- 显示客户端连接和客户端断开数量
当有新的连接信号,就进入ServerWidget::v_SlotConnection槽函数
//处理客户端连接
connect(tcpServer, &QTcpServer::newConnection, this, &ServerWidget::v_SlotConnection);
处理连接的函数
void ServerWidget::v_SlotConnection()
{
...
clients.append(tcpSocket);//客户端链表,有新的客户端就在末尾加入
...
//lcd控件 数字+1
int_linkNum++;
ui->linkNumber->display(int_linkNum);
//在这里处理断开连接的客户端
connect(tcpSocket, &QTcpSocket::disconnected, this, &ServerWidget::v_SlotDisconnection);
...
}
处理断开连接的函数
void ServerWidget::v_SlotDisconnection()
{
tcpSocket = (QTcpSocket *)this->sender();//得到发出信号的客户端
QString temp = QString("[%1:%2]:退出").arg(tcpSocket->peerAddress().toString()).arg(tcpSocket->peerPort());
ui->textEditReadonly->append(temp);
//从链表中删除
for(int i=0;i<clients.length();i++)
{
if(clients.at(i)->peerAddress() == tcpSocket->peerAddress())
{
if(clients.at(i)->peerPort() == tcpSocket->peerPort())
{
clients.removeAt(i);
//下拉框去除该客户端
ui->comboBox_clientLink->removeItem(i+1);
break;
}
}
}
//lcd显示的数量减1
int_linkNum--;
ui->linkNumber->display(int_linkNum);
}
当某一个Object emit一个signal的时候,它就是一个sender,系统会记录下当前是谁emit出这个signal的,所以你在对应的slot里就可以通过 sender()得到当前是谁invoke了你的slot,对应的是QObject->d->sender.(解释的说明来源:链接: link.
)
- 给所有客户端发送文件,给单独选中的客户端发送文件(下拉框选择)
(1)给所有客户端发送文件
下拉框默认加一个"All connections"
//处理连接
void ServerWidget::MCU_send_file()
{
...
ui->comboBox_clientLink->addItem("All connections");
...
//发送文件按钮
void ServerWidget::on_buttonFile_clicked()
{
ui->buttonFile->setEnabled(false);
//下拉框为第一个(即"All connections")
if(ui->comboBox_clientLink->currentIndex()==0)
{
for(int i=0;i<clients.length();i++)
{
//遍历的给所有客户端发送文件
v_SendData(clients.at(i));
}
}
...
}
(2)给单独选中的客户端发送文件(下拉框选择)
说明:下拉框activated信号的QString和int分别为下拉框的字符串和行数(从零开始)
void ServerWidget::on_comboBox_clientLink_activated(int index)
{
qDebug()<<index;
...
//选中客户端
tcpSocket_choice=clients.at(index-1);
...
}
//发送文件按钮
void ServerWidget::on_buttonFile_clicked()
{
...
else
{
v_SendData(tcpSocket_choice);
}
...
}
发送文件流程
1.读取
QByteArray outBlock;//读取文件缓冲区
void ServerWidget::on_buttonChoose_clicked()
{
...
//打开文件
bool isOk = file.open(QIODevice::ReadOnly);
...
outBlock=file.read(file.size());//读取文件
file.close();
...
}
2.发送
void ServerWidget::v_SendData(QTcpSocket *tcpSocket_sendfile)
{
...
qint64 ret = tcpSocket_sendfile->write(outBlock,outBlock.size());
tcpSocket->waitForBytesWritten();
...
}
- 接收客户端发过来的指令(分别有进度条,下面16个io_in点亮,8个io_out)
void ServerWidget::v_SlotConnection()
{
...
connect(tcpSocket, &QTcpSocket::readyRead, this, &ServerWidget::v_ReadDatafromclient);
...
}
void ServerWidget::v_ReadDatafromclient()
{
...
//tcpSocket_choice为下拉框选中的客户端
Fun_num = tcpSocket_choice->readAll().toInt();
...
}
第一次写qt,有什么不对的地方请指出,谢谢。