Ser
cpp
=================================================================
#include "app.h"
#include "ui_app.h"APP::APP(QWidget *parent):QWidget(parent),ui(new Ui::APP)
{ui->setupUi(this);this->resize(550,400);ui->Line->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->Line->setFont(QFont("楷体",10));ui->LB1->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->LB1->setFont(QFont("楷体",13));//ui->Listw->setFont(QFont("楷体",8));ui->SB1->setFont(QFont("华文行楷",15));server = new QTcpServer(this); //创建服务器server}APP::~APP()
{delete ui;
}//Start服务器按钮对应的槽函数
void APP::on_SB1_clicked()
{//获取UI界面的port号quint16 port = ui->Line->text().toUInt();//服务器设定为监听状态//bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any,quint16 port = 0)//参数1:监听的主地址,any=>所有的;也可给定特定的地址进行监听//参数2:通过指定的端口号进行访问服务器,若为0,则表示由服务器自动分配,若非0则表示指定端口号//返回值,成功<=true;失败<=false;if(!server->listen(QHostAddress::Any,port)){QMessageBox::critical(this,"失败","Server启动失败");return;}else{QMessageBox::about(this,"成功","启动成功");}//Server启动成功,对客户端进行监听//有客户端发送来的链接请求,服务器会自动发送一个newConenction信号//将该信号连接到对应的槽函数中处理相关逻辑connect(server,&QTcpServer::newConnection,this,&APP::newConnection_slot);}
void APP::newConnection_slot()//处理newConnection信号的槽函数的实现
{qDebug() <<"Cli连接了请求了";//获取最新链接的客户端套接字//原型 [virtual] QTcpsocket *QTcpseicer::nextPendingConnection()//参数:无//返回值:最新链接客户端套接字的指针QTcpSocket *s = server->nextPendingConnection();clientList.push_back(s);//将获取到的套接字存放到客户端的容器中//此时已经链接上客户端了//如果该套接字有数据数据项服务器发送过来,则该套接字就会自动发射一个readyRead信号//用该信号处理相关函数connect(s,&QTcpSocket::readyRead,this,&APP::readyRead_slot);
}void APP::readyRead_slot()//关于readyRead信号对应的槽函数
{//排除客户端链表中无效的客户端套接字for(int i=0;i<clientList.count();i++){//判断套接字状态//原型:SocketState state() const//功能:返回客户端套接字状态//参数:无//返回值:客户端的状态,若结果为,则表示未链接if(clientList[i]->state() == 0){clientList.removeAt(i);//若为,则removed掉}}//便利所有的客户端查看哪个客户端发来的数据for(int i=0;i<clientList.count();i++){//原型:qint64 bytesAvailiable() const override//功能:返回客户端套接字中可读的字节个数//参数:无//返回值:当前客户端的可读的字节个数,若结果为,则表示无数据可读if(clientList[i]->bytesAvailable() != 0){//读取当前客户端的相关数据//原型:QByteArray readAll()//功能:读取当前套接字中的所有数据,返回一个字节数组//参数:无//返回值:返回的字节数组QByteArray msg = clientList[i]->readAll();//数据=>UI界面上ui->Listw->addItem(QString::fromLocal8Bit(msg));//接收到的消息,发送给所有的客户端for(int j=0;j<clientList.count();j++){clientList[j]->write(msg);}}}
}
.h
=================================================================
#ifndef APP_H
#define APP_H
//头文件
#include <QWidget>
#include <QTcpServer>//服务器
#include <QTcpSocket>//客户段
#include <QList>//链表 存放客户端的容器
#include <QDebug>
#include <QMessageBox>//消息QT_BEGIN_NAMESPACE
namespace Ui { class APP; }
QT_END_NAMESPACEclass APP : public QWidget
{Q_OBJECTpublic:APP(QWidget *parent = nullptr);~APP();//QList<QTcpServer *> clientList;private slots:void on_SB1_clicked();void newConnection_slot();void readyRead_slot();private:Ui::APP *ui;QTcpServer *server;QList<QTcpSocket *> clientList;
};
#endif // APP_HT1.pro
=================================================================
QT += core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \app.cppHEADERS += \app.hFORMS += \app.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
mian.cpp
=================================================================
#include "app.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);APP w;w.show();return a.exec();
}
Cli
cpp
=================================================================
#include "cli.h"
#include "ui_cli.h"Cli::Cli(QWidget *parent):QWidget(parent),ui(new Ui::Cli)
{ui->setupUi(this);socket = new QTcpSocket(this);//客户端指针实例化空间ui->USER->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->USER->setFont(QFont("楷体",10));ui->USERed->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->USERed->setFont(QFont("楷体",10));ui->IP->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->IP->setFont(QFont("楷体",10));ui->IPed->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->IPed->setFont(QFont("楷体",10));ui->PORT->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->PORT->setFont(QFont("楷体",10));ui->PORTed->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->PORTed->setFont(QFont("楷体",10));ui->msged->setFont(QFont("等线",10));ui->connectSB1_2->setFont(QFont("华文行楷",15));ui->disconnectSB2_2->setFont(QFont("华文行楷",15));ui->sendSB3->setFont(QFont("华文行楷",15));//connect(ui->connectSB1_2,&QPushButton::clicked,this,&Cli::readyRead_slot);//如果链接Server成功(只链接一次),客户端就会发射一个connected的信号,将该信号链接槽函数connect(socket,&QTcpSocket::connected,this,&Cli::connect_slot);//客户端与服务器链接成功后,若服务器向客户端发送来数据,则客户端就会自动发射一个readyRead信号//Ser<=>Cli,if(Ser=>),CLi=>readyReadconnect(socket,&QTcpSocket::readyRead,this,&Cli::readyRead_slot);//客户端与服务器链接成功后,客户端就会自动发射一个disconnected信号connect(socket,&QTcpSocket::disconnected,this,&Cli::disconnected_slot);
}Cli::~Cli()
{delete ui;
}void Cli::on_connectSB1_2_clicked()
{//userName = ui->USERed->text();//get USERQString s1 = "八嘎";userName = s1;//QString hostName = ui->IPed->text();//get IPQString s2 = "192.168.124.72";QString hostName = s2;quint16 port = ui->PORTed->text().toUInt();//get PORTqDebug() << "获取信息-----";//链接主机socket->connectToHost(hostName,port);qDebug() << "链接成功";//if链接服务器成功,Cli发送一个connect信号,由于该链接之链接一次所以写于构造函数中
}void Cli::connect_slot()
{QMessageBox::information(this,"连线","链接成功");QString msg = userName + ":进入聊天室";socket->write(msg.toLocal8Bit());
}void Cli::readyRead_slot()
{//读取客户端的数据QByteArray msg = socket->readAll();//数据展示在UI界面上ui->Listw->addItem(QString::fromLocal8Bit(msg));
}void Cli::on_sendSB3_clicked()
{//获取ui界面输入的内容QString m = ui->msged->text();//整合信息QString msg = userName + ": " + m;socket->write(msg.toLocal8Bit());
}void Cli::on_disconnectSB2_2_clicked()//断开服务器
{//准备要发送的信息QString msg = userName + ": 离开聊天室";socket->write(msg.toLocal8Bit());socket->disconnectFromHost();//断开后,客户端自动发送一个disconnect信号=>将该connect信号与槽函数链接
}void Cli::disconnected_slot()
{QMessageBox::information(this,"断开链接","断开成功");
}void Cli::on_SB4_clicked()
{ui->Listw->clear();
}
.h
=================================================================
#ifndef CLI_H
#define CLI_H#include <QWidget>
#include <QTcpServer>//服务器
#include <QTcpSocket>//客户段
#include <QList>//链表 存放客户端的容器
#include <QDebug>
#include <QMessageBox>//消息QT_BEGIN_NAMESPACE
namespace Ui { class Cli; }
QT_END_NAMESPACEclass Cli : public QWidget
{Q_OBJECTpublic:Cli(QWidget *parent = nullptr);~Cli();private slots:void on_connectSB1_2_clicked();void connect_slot();//处理connect信号的槽函数void readyRead_slot();//处理readyRead信号的槽函数void on_sendSB3_clicked();//发送数据void on_disconnectSB2_2_clicked();//断开服务器void disconnected_slot();//disconnected信号 断开服务器提示void on_SB4_clicked();private:Ui::Cli *ui;//QTcpServer *server;QTcpSocket *socket;QString userName;};
#endif // CLI_H
.pro
=================================================================
QT += core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \cli.cppHEADERS += \cli.hFORMS += \cli.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
.main
=================================================================
#include "cli.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Cli w;w.show();return a.exec();
}