目录
一、服务器
1.1 tcp.pro
1.2 widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QList>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public slots:
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_newConnection_sloat();
void on_pushButton_clicked();
void on_readyRead_sloat();
void send(QString mes);
private:
Ui::Widget *ui;
QTcpServer *server;
bool isok;
QList<QTcpSocket *> socketList;
};
#endif // WIDGET_H
1.3 widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QString>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
server =new QTcpServer(this);
isok=false;
}
Widget::~Widget()
{
delete ui;
}
//启动服务器按钮对应的槽函数
void Widget::on_pushButton_clicked()
{
//ui->textEdit->setEnabled(false);
if(isok == false)
{
quint16 port=ui->textEdit->toPlainText().toInt();
//服务器设置为监听
server->listen(QHostAddress::Any,port);
if(server->listen(QHostAddress::Any, port))
{
qDebug()<<"服务创建成功";
}else {
qDebug()<<"服务创建失败";
}
isok=true;
ui->textEdit->setEnabled(false);
ui->pushButton->setText("关闭服务器");
connect(server,&QTcpServer::newConnection,this,&Widget::on_newConnection_sloat);
}else
{
ui->textEdit->setEnabled(true);
isok=false;
ui->pushButton->setText("启动服务器");
close();
}
}
//获取连接客户端的套接字
void Widget::on_newConnection_sloat()
{
QTcpSocket *socket=server->nextPendingConnection();
socketList.append(socket);
connect(socket,&QTcpSocket::readyRead,this,&Widget::on_readyRead_sloat);
}
//接收客户端发来的消息
void Widget::on_readyRead_sloat()
{
qDebug()<<socketList.count();
for (int i=0;i<socketList.count();i++)
{
if(socketList.at(i)->state() == false)
{
socketList.removeAt(i);
}
}
for (quint16 i=0;i<socketList.count();i++)
{
if(socketList.at(i)->bytesAvailable())
{
QString mes=QString::fromLocal8Bit(socketList.at(i)->readAll());
ui->listwidget->addItem(mes);
send(mes);
}
}
}
//自定义发送消息
void Widget::send(QString mes)
{
for (int i=0;i<socketList.count();i++)
{
socketList.at(i)->write(mes.toLocal8Bit());
}
}
1.4 mian.cpp
没有任何更改
二、客户端
2.1 tcp_khd.pro
2.2 widget.h
#include <QString>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_connectbtn_clicked();
void on_connected_sloat();
void on_disconnected_sloat();
void on_readyRead_sloat();
void on_sendbtn_clicked();
private:
Ui::Widget *ui;
QTcpSocket *socket;
QString userName;
bool isok;
};
#endif // WIDGET_H
2.3 widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//实例化socket
socket=new QTcpSocket(this);
//连接状态初始值
isok=false;
connect(socket,&QTcpSocket::connected,this,&Widget::on_connected_sloat);
connect(socket,&QTcpSocket::disconnected,this,&Widget::on_disconnected_sloat);
connect(socket,&QTcpSocket::readyRead,this,&Widget::on_readyRead_sloat);
}
Widget::~Widget()
{
delete ui;
}
//连接服务器按钮对应槽函数
void Widget::on_connectbtn_clicked()
{
QString ip=ui->ipEdit->text();
quint16 port=quint16(ui->portEdit->text().toInt());
//判断是否为连接状态
if(isok == false)
{
//连接服务器
socket->connectToHost(QHostAddress(ip),port);
ui->connectbtn->setText("断开连接");
isok=true;
ui->ipEdit->setEnabled(false);
ui->userNameEdit->setEnabled(false);
ui->portEdit->setEnabled(false);
}else
{
//断开服务器
userName=ui->userNameEdit->text();
QString mes=userName+"退出群聊";
socket->write(mes.toLocal8Bit());
socket->disconnectFromHost();
ui->connectbtn->setText("连接服务器");
isok=false;
}
}
//连接服务器的槽函数
void Widget::on_connected_sloat()
{
userName=ui->userNameEdit->text();
QString mes=userName+"加入群聊";
socket->write(mes.toLocal8Bit());
}
//断开服务器的槽函数
void Widget::on_disconnected_sloat()
{
ui->ipEdit->setEnabled(true);
ui->userNameEdit->setEnabled(true);
ui->portEdit->setEnabled(true);
}
//readyRead信号的槽函数
void Widget::on_readyRead_sloat()
{
QString mes=QString::fromLocal8Bit(socket->readAll());
ui->listWidget->addItem(mes);
}
//发送按钮的槽
void Widget::on_sendbtn_clicked()
{
userName=ui->userNameEdit->text();
QString mes=userName+":"+ui->mesEdit->text();
socket->write(mes.toLocal8Bit());
}
2.4 mian.cpp
没有任何更改
三、执行结果