目录
【注意这里是服务器向多个客户端发起广播,不支持客户端通过服务器与另一个服务器进行沟通(后续会进行更新)】
.h文件
form.h [客户端]
#ifndef FORM_H
#define FORM_H
#include <QWidget>
#include <QTimer>
#include <QTcpSocket>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = nullptr);
~Form();
private:
Ui::Form *ui;
QTcpSocket *kehuduan;
};
#endif // FORM_H
mainwindow.h [服务器]
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>//服务器类
#include <QTcpSocket>
#include <QVector>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QTcpServer *server;
//QTcpSocket *kehuduan;
QVector <QTcpSocket*> ret;
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
.cpp文件
form.cpp [客户端]
#include "form.h"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
//客户端
ui->setupUi(this);
//实例化服务器对象(this自动释放)
kehuduan= new QTcpSocket(this);
setWindowTitle("客户端1");
ui->lineEdit_ip->setText("127.0.0.1");
ui->lineEdit_duankou->setText("8888");
ui->pushButton_duankou->setText("端口未连接");
QTimer *time1 = new QTimer(this);
time1->setInterval(1000);
time1->start();
// connect(time1,&QTimer::timeout,this,[=](){
// if( ui->pushButton_duankou->text() == "端口已连接"){
// ui->pushButton_duankou->setText("端口未连接");
// kehuduan->close();//断开连接
// //kehuduan->deleteLater();//删除实例化对象
// return ;
// }
// });
// connect(ui->pushButton_duankou,&QPushButton::clicked,this,[=](){
// time1->timeout(1);
// });
//连接服务器
connect(ui->pushButton_duankou,&QPushButton::clicked ,[=](){
if( ui->pushButton_duankou->text() == "端口已连接"){
ui->pushButton_duankou->setText("端口未连接");
//释放标志
QString str ="%close%";
//QString转char* 。toutf8
kehuduan->write(str.toUtf8());
ui->textBrowser->append("客户端1退出连接");
kehuduan->close();
//kehuduan->deleteLater();
return;
}
QString ip = ui->lineEdit_ip->text();
unsigned short port = ui->lineEdit_duankou->text().toUShort();
//连接服务器
kehuduan->connectToHost(ip,port);
ui->pushButton_duankou->setText("端口已连接");
//ui->pushButton_duankou->setDisabled(true);
});
//给客户端发送数据
connect(ui->pushButton_fasong,&QPushButton::clicked,this,[=](){
QString str = this->windowTitle()+":"+ ui->textEdit->toPlainText();
//QString转char* 。toutf8
kehuduan->write(str.toUtf8());
ui->textBrowser->append(str);
});
connect(kehuduan,&QTcpSocket::readyRead,this,[=](){
QByteArray data = kehuduan->readAll();
ui->textBrowser->append("服务端:"+data);
});
}
Form::~Form()
{
delete ui;
}
mainwindow.cpp [服务器]
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//服务器端
ui->setupUi(this);
//实例化服务器对象(this自动释放)
server = new QTcpServer(this);
ui->lineEdit_duankou->setText("8888");
//启动监听按钮【无问题】
connect(ui->pushButton_duankou,&QPushButton::clicked,[=](){
unsigned short port = ui->lineEdit_duankou->text().toUShort();
//开监听【ip+port】
server->listen(QHostAddress::Any,port);
ui->pushButton_duankou->setDisabled(true);
});
//等待客户端连接【无问题】
connect(server,&QTcpServer::newConnection,this,[=](){
// kehuduan = server->nextPendingConnection();
ret.push_back(server->nextPendingConnection());
int len = ret.size();
QMessageBox::information(this,"通知",QString("现有客户端数量%1").arg(ret.size()));
for(int i=0 ; i != len ; i++){
connect(ret[i],&QTcpSocket::readyRead,this,[=](){
QByteArray data = ret[i]->readAll();
if(data == "%close%") {
ret.erase(ret.begin()+i);
//ret.resize(ret.size()-1);
QMessageBox::information(this,"通知",QString("现有数量%1").arg(ret.size()));
}
if(data != NULL)
ui->textBrowser->append(data);
});
}
});
//给客户端发送数据
connect(ui->pushButton_fasong,&QPushButton::clicked,this,[=](){
QString str = ui->textEdit->toPlainText();
//QString转char* 。toutf8
for(int i=0 ; i<ret.size() ; i++){
ret[i]->write(str.toUtf8());
}
ui->textBrowser->append("服务端:"+str);
});
}
MainWindow::~MainWindow()
{
//如果不指定要在析构delete
delete ui;
}
main.cpp
这里创建了客户端数组
可以通过改变main.cpp里的len改变客户端数量
#include "mainwindow.h"
#include "form.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
int len = 2;
Form *f = new Form[len];
for(int i=0 ; i<len ; i++){
f[i].setWindowTitle(QString("客户端%1").arg(i+1));
f[i].show();
}
// client2 c2;
// c2.show();
// client3 c3;
// c3.show();
return a.exec();
}
实现细节
实现多客户端接受
通过再服务器端声明QTCPSocket类来接受客户端的数据实现对多个客户端的记录
QVector <QTcpSocket> ret;*
【注意这里是通过遍历一遍vector容器来判断是谁发来了数据,一旦客户端过多性能会不佳】
遍历和删除细节
for(int i=0 ; i != ret.size(); i++)//这里最佳的遍历结束符应当是!=而不是<
ret.erase(ret.begin()+i); //删除erase而不是swap()和pop_back();
效果图
代码压缩包
https://pan.baidu.com/s/1oHVA1Fo_AOxN1h0go415Sg
提取码:5v6b