服务器:
- #include "widget.h"
- #include "ui_widget.h"
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::Widget)
- {
- ui->setupUi(this);
-
- //给服务器指针实例化对象
- server = new QTcpServer(this);
- }
-
- Widget::~Widget()
- {
- delete ui;
- }
-
- //启动服务器按钮对应的槽函数
- void Widget::on_pushButton_clicked()
- {
- //获取ui界面上的端口号
- quint16 port = ui->lineEdit->text().toUInt();
-
- //将服务器设置成监听状态
- if(!server->listen(QHostAddress::Any, port))
- {
- QMessageBox::critical(this, "失败", "服务器启动失败");
- return;
- }
- else
- {
- QMessageBox::information(this, "成功", "服务器启动成功");
- }
-
- //此时表明服务器启动成功,并对客户端连接进行监听
- //如果有客户端向服务器发射连接请求,那么该服务器就会自动发射一个newConnection的信号
- connect(server, &QTcpServer::newConnection, this, &Widget::newConnection_slot);
- }
-
- //处理newConnection
- void Widget::newConnection_slot()
- {
- qDebug() << "有新的客户端发来连接请求了";
-
- //获取最新连接的客户端套接字
- QTcpSocket *s = server->nextPendingConnection();
-
- //将获取的套接字存放到客户端容器中
- clientlist.push_back(s);
-
- connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
- }
-
- void Widget::readyRead_slot()
- {
- //删除客户端链表中无效的客户端套接字
- for(int i=0; i
count(); i++) - {
- //判断套接字的状态
- if(clientlist[i]->state() == 0) //SocketState state() const
- { //功能:返回客户端套接字的状态
- clientlist.removeAt(i);
- } //返回值:客户端的状态,如果结果为0,表示未连接
- }
-
- //遍历所有客户端,查看是哪个客户端发来数据
- for(int i=0; i
count(); i++) - {
- if(clientlist[i]->bytesAvailable() != 0)
- {
- //读取当前客户端的相关数据
- QByteArray msg = clientlist[i]->readAll();
-
- //将数据展示到ui界面上
- ui->listWidget->addItem(QString::fromLocal8Bit(msg));
-
- //将接受的信息,发送给所有客户端
- for(int j=0; j
count(); j++) - {
- clientlist[j]->write(msg);
- }
- }
- }
- }
客户端:
- #include "widget.h"
- #include "ui_widget.h"
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::Widget)
- {
- ui->setupUi(this);
-
- socket = new QTcpSocket(this);
-
- connect(socket, &QTcpSocket::connected, this, &Widget::connected_slot);
-
- //客户端与服务器连接成功后,服务器向客户端发来数据,那么客户端就会发射一个readyRead信号
- connect(socket, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
-
- connect(socket, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);
- }
-
- Widget::~Widget()
- {
- delete ui;
- }
-
-
- void Widget::on_connectBtn_clicked()
- {
- if(ui->connectBtn->text() == "连接服务器")
- {
- //获取ui界面信息
- Name = ui->userNameEdit->text();
- QString hostName = ui->ipEdit->text();
- quint16 port = ui->portEdit->text().toUInt();
-
- //连接到主机
- socket->connectToHost(hostName, port);
-
- //如果连接服务器成功,该客户端就会发射一个connected的信号
-
- ui->connectBtn->setText("断开服务器");
- }
- else if(ui->connectBtn->text() == "断开服务器")
- {
- QString msg = Name + ":拿手好戏后 离开聊天室";
- socket->write(msg.toLocal8Bit());
-
- //断开客户端与服务器的连接
- socket->disconnectFromHost();
- //当客户端与服务器断开,该客户端就会自动发送一个disconnected的信号
-
- ui->connectBtn->setText("连接服务器");
- }
- }
-
- //处理conneed信号的槽函数定义
- void Widget::connected_slot()
- {
- QMessageBox::information(this, "成功", "连接服务器成功");
-
- //顺便向服务器发送一条信息,说:***,进入聊天室
- QString msg = Name + ":带着power 进入聊天室";
- socket->write(msg.toLocal8Bit());
- }
-
-
- void Widget::readyRead_slot()
- {
- QByteArray msg = socket->readAll();
-
- ui->msgList->addItem(QString::fromLocal8Bit(msg));
- }
-
-
- void Widget::on_sendBtn_clicked()
- {
- //获取ui界面的编辑的文本
- QString m = ui->msgEdit->text();
-
- //整合要发送的信息
- QString msg = Name + ":" + m;
-
- //将信息发送给服务器
- socket->write(msg.toLocal8Bit());
-
- //发送后清空文本
- ui->msgEdit->clear();
- }
-
- void Widget::disconnected_slot()
- {
- QMessageBox::information(this, "退出", "断开服务器");
- }
思维导图: