服务器:
#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<clientlist.count(); i++){//判断套接字的状态if(clientlist[i]->state() == 0) //SocketState state() const{ //功能:返回客户端套接字的状态clientlist.removeAt(i);} //返回值:客户端的状态,如果结果为0,表示未连接}//遍历所有客户端,查看是哪个客户端发来数据for(int i=0; i<clientlist.count(); i++){if(clientlist[i]->bytesAvailable() != 0){//读取当前客户端的相关数据QByteArray msg = clientlist[i]->readAll();//将数据展示到ui界面上ui->listWidget->addItem(QString::fromLocal8Bit(msg));//将接受的信息,发送给所有客户端for(int j=0; j<clientlist.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, "退出", "断开服务器");
}
思维导图: