服务器:
头文件:
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- QT_BEGIN_NAMESPACE
- namespace Ui { class Widget; }
- QT_END_NAMESPACE
-
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- Widget(QWidget *parent = nullptr);
- ~Widget();
-
- private:
- Ui::Widget *ui;
-
- //客户端指针
- QTcpSocket *client;
- //存储用户名
- QString uname;
-
- //聊天框
- QListWidget *text;
- //消息发送框
- QLineEdit *msg;
- //发送按钮
- QPushButton *send;
- //用户名、
- QLabel *userLab;
- //IP
- QLabel *ipLab;
- //PORT
- QLabel *portLab;
- //用户输入框
- QLineEdit *unameEdit;
- //IP输入框
- QLineEdit *ipEdit;
- //端口输入框
- QLineEdit *portEdit;
- //连接服务器按钮
- QPushButton *bconnect;
- //断开服务器按钮
- QPushButton *bdisconnect;
-
- public slots:
- //连接按钮槽函数
- void connectBtn_clicked();
- //声明自定义处理connected信号的槽函数
- void connected_slot();
- //声明自定义处理readyRead信号的槽函数
- void readyRead_slot();
- //声明自定义处理disconnected信号的槽函数
- void disconnected_slot();
- //发送按钮槽函数
- void sendBtn_clicked();
- //断开连接槽函数
- void disconnectBtn_clicked();
- };
- #endif // WIDGET_H
widget.cpp文件
- #include "widget.h"
- #include "ui_widget.h"
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::Widget)
- {
- ui->setupUi(this);
- this->setFixedSize(720,680);
-
- //聊天框
- text = new QListWidget(this);
- text->setFixedSize(720,400);
- //消息发送框
- msg = new QLineEdit(this);
- msg->resize(500,50);
- msg->move(10,420);
- //发送按钮
- send = new QPushButton(this);
- send->setText("发送");
- send->resize(150,50);
- send->move(520,420);
- //用户名
- userLab = new QLabel(this);
- userLab->setText("用户名:");
- userLab->setAlignment(Qt::AlignCenter);
- userLab->resize(100,30);
- userLab->move(30,500);
- //IP
- ipLab = new QLabel(this);
- ipLab->setText("IP:");
- ipLab->setAlignment(Qt::AlignCenter);
- ipLab->resize(100,30);
- ipLab->move(30,550);
- //PORT
- portLab = new QLabel(this);
- portLab->setText("Port:");
- portLab->setAlignment(Qt::AlignCenter);
- portLab->resize(100,30);
- portLab->move(30,600);
- //用户输入框
- unameEdit = new QLineEdit(this);
- unameEdit->resize(300,30);
- unameEdit->move(140,500);
- //IP输入框
- ipEdit = new QLineEdit(this);
- ipEdit->resize(300,30);
- ipEdit->move(140,550);
- //端口输入框
- portEdit = new QLineEdit(this);
- portEdit->resize(300,30);
- portEdit->move(140,600);
- //连接服务器按钮
- bconnect = new QPushButton(this);
- bconnect->resize(120,50);
- bconnect->setText("连接");
- bconnect->move(520,500);
- //断开服务器按钮
- bdisconnect = new QPushButton(this);
- bdisconnect->resize(120,50);
- bdisconnect->setText("断开连接");
- bdisconnect->move(520,580);
-
- client = new QTcpSocket(this);
- //连接按钮信号
- connect(bconnect,&QPushButton::clicked,this,&Widget::connectBtn_clicked);
- //连接上后客户端自动发送一个connected信号,只需要连接一次
- connect(client,&QTcpSocket::connected,this,&Widget::connected_slot);
- //如果服务器有数据发送给该客户端,那么该套接字就会自动发射一个readyRead信号
- connect(client, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
- //发送按钮
- connect(send,&QPushButton::clicked,this,&Widget::sendBtn_clicked);
- //当成功与服务器断开连接后,该客户端就会自动发射一个disconnected的信号
- connect(client, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);
- }
-
- Widget::~Widget()
- {
- delete ui;
-
- }
-
- //连接按钮槽函数
- void Widget::connectBtn_clicked()
- {
- //获取ip和端口
- QString ip = ipEdit->text();
- quint16 port = portEdit->text().toUInt();
-
- //连接主机
- client->connectToHost(ip,port);
- }
- //声明自定义处理connected信号的槽函数
- void Widget::connected_slot()
- {
- QMessageBox::information(this,"","连接服务器成功");
-
- uname = unameEdit->text();
- QString msgs = uname+":进入聊天室";
-
- client->write(msgs.toLocal8Bit());
-
- msg->setEnabled(true);
- send->setEnabled(true);
- bdisconnect->setEnabled(true);
- unameEdit->setEnabled(false);
- ipEdit->setEnabled(false);
- portEdit->setEnabled(false);
- bconnect->setEnabled(false);
-
- }
- //声明自定义处理readyRead信号的槽函数
- void Widget::readyRead_slot()
- {
- //接收到服务器消息后
- QByteArray msgbox = client->readAll();
- //显示
- text->addItem(QString::fromLocal8Bit(msgbox));
- }
- //声明自定义处理disconnected信号的槽函数
- void Widget::disconnected_slot()
- {
- QString msgbox = uname+":离开聊天室";
- client->write(msgbox.toLocal8Bit());
- //断开后客户端会发送一个disconnected信号
- client->disconnectFromHost();
- }
- //发送按钮槽函数
- void Widget::sendBtn_clicked()
- {
- QString msgbox = msg->text();
- msgbox = uname+":"+msgbox;
- //发送
- client->write(msgbox.toLocal8Bit());
- msg->clear();
-
- }
- //断开连接槽函数
- void Widget::disconnectBtn_clicked()
- {
- QMessageBox::information(this,"","成功断开");
- msg->setEnabled(false);
- send->setEnabled(false);
- bdisconnect->setEnabled(false);
- unameEdit->setEnabled(true);
- ipEdit->setEnabled(true);
- portEdit->setEnabled(true);
- bconnect->setEnabled(true);
- }
-
头文件
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- QT_BEGIN_NAMESPACE
- namespace Ui { class Widget; }
- QT_END_NAMESPACE
-
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- Widget(QWidget *parent = nullptr);
- ~Widget();
-
- private:
- Ui::Widget *ui;
- //定义服务器指针
- QTcpServer *server;
- //定义客户端容器
- QList
socketList; -
- //对话框
- QListWidget *text;
- //端口号
- QLabel * l_port;
- //端口输入框
- QLineEdit *edit_port;
- //启动按钮
- QPushButton *bstart;
-
- private slots:
- //按键槽函数
- void start_clicked();
- //连接槽函数
- void newConnection_slot();
- //readyRead信号处理槽函数
- void readyRead_slot();
-
- };
- #endif // WIDGET_H
widget.cpp
- #include "widget.h"
- #include "ui_widget.h"
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::Widget)
- {
- ui->setupUi(this);
-
- this->setFixedSize(680,500);
-
- //对话框
- text = new QListWidget(this);
- text->setFixedSize(680,350);
- //端口号
- l_port = new QLabel(this);
- l_port->setText("端口号:");
- l_port->resize(50,30);
- l_port->move(50,400);
-
- //端口输入框
- edit_port = new QLineEdit(this);
- edit_port->resize(380,30);
- edit_port->move(120,400);
- //启动按钮
- bstart = new QPushButton(this);
- bstart->setText("启动服务器");
- bstart->resize(100,30);
- bstart->move(520,400);
-
- server = new QTcpServer(this);
-
- connect(bstart,&QPushButton::clicked,this,&Widget::start_clicked);
- }
-
- Widget::~Widget()
- {
- delete ui;
- }
-
- void Widget::start_clicked()
- {
- qDebug()<<"ok"; //测试
- //判断输入框中是否有内容
- if(edit_port->text() == NULL)
- {
- QMessageBox::information(this,"错误","端口号为空!");
- }
- else
- {
- //获取输入框中的内容
- quint16 port = edit_port->text().toUInt();
- qDebug()<
- QString ip = "192.168.1.2";
- QHostAddress address(ip);
-
- //将服务器设置成监听状态,监听客户段发来的连接请求
- if(server->listen(QHostAddress::Any,port))
- {
- QMessageBox::information(this,"","服务器启动成功");
- }
- else
- {
- QMessageBox::information(this,"","服务器启动失败");
- }
-
- //此时服务器已经进入监听状态,客户段发来连接请求,服务器就会自动发射一个newConnext信号
- connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);
- }
- }
-
- void Widget::newConnection_slot()
- {
- qDebug()<<"有客户连接";
- //获取最新连接的客户段套接字
- QTcpSocket *client = server->nextPendingConnection();
- //将套接字放入客户端容器
- socketList.push_back(client);
-
- //监听套接字,有数据则客户端会发送一个readyRead信号
- connect(client,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
- }
-
- void Widget::readyRead_slot()
- {
- //移除无效客户端
- for (int i = 0;i
count();i++) - {
- //套接字状态为0表示无效客户端
- if(socketList.at(i)->state() == 0)
- {
- socketList.removeAt(i);
- }
- }
- //遍历套接字有消息发送给其他客户端
- for (int i = 0;i
count();i++) - {
- //获取套接字是否有有效数据
- if(socketList.at(i)->bytesAvailable() != 0)
- {
- //获取套接字内信息
- QByteArray msg = socketList.at(i)->readAll();
- text->addItem(QString::fromLocal8Bit(msg));
- for (int j = 0;j
count();j++) - {
- socketList.at(j)->write(msg);
-
- }
- }
- }
- }
-