源码下载点这里
已经实现对客户端消息群发以及单独发送,测试是网上下的网络调试助手测试。
因为与单片机进行通信,所以只研究了下tcp的服务器端
qt的tcp服务器有两个socket一个是监听套接字(QTcpServer),一个是通信套接字(QTcpSocket),创建一个tcpServer对象设置好端口Ip后开始监听
tcpServer->listen(QHostAddress(ip),port)
成功监听返回true,当有连接连上tcpServer会触发newConnection信号,newConnection信号对应的槽函数进行通信套接字的连接,以下是监听套接字连接与断开源码
void server::on_pushButton_connect_clicked()
{
QString temp;
if(tcpServer->isListening()==true)//服务器正在监听
{
if(tcpSocket != nullptr)//判断是否有客户端连接
{
for(int i=tcpClientList.length()-1;i>=0;i--)//断开所有连接应从最后开始断开
{
//temp =QString("[%1:%2]:退出").arg(tcpClientList.at(i)->peerAddress().toString()).arg(tcpClientList.at(i)->peerPort());
//ui->textEdit_GetText->append(temp);
tcpClientList.at(i)->disconnectFromHost();//会触发disconnected信号
//tcpClientList.removeAt(i);
}
if(tcpClientList.isEmpty()==true)
{
tcpServer->close(); //关闭服务器
tcpSocket=nullptr;
ui->textEdit_GetText->append("停止监听成功");
ui->pushButton_connect->setText("连接");
disconnect(tcpServer,&QTcpServer::newConnection,this,&server::NewConnection);
}
}
else
{
QString str = "当前没有连接,可重新监听";
tcpServer->close();
ui->textEdit_GetText->append(str);
ui->pushButton_connect->setText("连接");
disconnect(tcpServer,&QTcpServer::newConnection,this,&server::NewConnection);
}
}
else
{
//获取IP和端口
if(ui->lineEdit_Ip->text() != "")
ip = ui->lineEdit_Ip->text();
ui->lineEdit_Ip->setText(ip);
if(ui->lineEdit_prot->text()=="")
{
port=8888;
}
else
{
port = quint16(ui->lineEdit_prot->text().toUInt());
}
ui->lineEdit_prot->setText(QString::number(port));
//if(true == tcpServer->listen(QHostAddress::Any,port))//监听所有Ip
if(true == tcpServer->listen(QHostAddress(ip),port))
{
ui->textEdit_GetText->append("开始监听");
ui->pushButton_connect->setText("停止");
connect(tcpServer,&QTcpServer::newConnection,this,&server::NewConnection);
}
else
{
ui->textEdit_GetText->append("监听失败");
return ;
}
}
}
处理连接信号
void server::NewConnection()
{
//取出建立好的套接字
tcpSocket = tcpServer->nextPendingConnection();
//获取对方Ip和端口
QString cip = tcpSocket->peerAddress().toString();
quint16 prot = tcpSocket->peerPort();
QString temp= QString("%1.%2:成功连接").arg(cip).arg(prot);
ui->textEdit_GetText->append(temp);
//添加到界面以及socket列表中
temp=temp.split(":")[0];
ui->comboBox_clinet->addItem(temp);
tcpClientList.append(tcpSocket);
connect(tcpSocket,&QTcpSocket::readyRead,this,&server::ReadyRead);
connect(tcpSocket,&QTcpSocket::disconnected,this,&server::disconnectedSlot);
}
客户端主动断开服务器连接会触发服务器的disconnected信号,同时tcpSocket的disconnectFromHost
方法也会触发disconnected信号,断开函数如下
void server::disconnectedSlot()
{
tcpSocket = (QTcpSocket *)this->sender();//得到发出信号的客户端
QString temp =QString("%1.%2:退出").arg(tcpSocket->peerAddress().toString()).arg(tcpSocket->peerPort());
ui->textEdit_GetText->append(temp);
temp=temp.split(":")[0];
//从链表中删除
for(int i=0;i<tcpClientList.length();i++)
{
if(tcpClientList.at(i)->peerAddress() == tcpSocket->peerAddress())
{
if(tcpClientList.at(i)->peerPort() == tcpSocket->peerPort())
{
if(ui->comboBox_clinet->itemText(i) == temp)
ui->comboBox_clinet->removeItem(i);
if(ui->comboBox_clinet->count()==0)
ui->comboBox_clinet->setCurrentText("客户端");
tcpClientList.removeAt(i);
break;
}
}
}
}