VsQt制作tcp通信服务端客户端小工具,可多客户端操作

1.Tcp通信核心类

QTcpServer
QTcpSocket
在这里插入图片描述
需新增模组 network ,右键项目选中Qt Project Settings
在这里插入图片描述
选中Qt Modules ,勾选Network模组点击ok即可
在这里插入图片描述

2.服务端代码

#include <QtWidgets/QMainWindow>
#include "ui_QtGuiTcpServer.h"
#include <QListWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QDateTime>
#include <QTcpSocket> 
#include <QTcpServer> 
#include <QDebug>
#include <QList>
#include <QMap>
#include <QTextEdit>
#include <QListWidgetItem>
#include <QMessageBox>
#include <QThread>

class QtGuiTcpServer : public QMainWindow
{
	Q_OBJECT

public:
	QtGuiTcpServer(QWidget *parent = Q_NULLPTR);
	~QtGuiTcpServer();
	void AddLog(QString mStr);
private:
	Ui::QtGuiTcpServerClass ui;
	QTcpServer *m_TcpServer = NULL;//服务端
	QMap<QString,QTcpSocket *> m_Sockets;//负责存储服务端与客户端通信的套接字集合

	private slots:
	void btn_Open_Clicked();
	void ListenConnectRequst();//服务端监听
	void TcpServerReadData();//服务端读数据
	void TcpClientDisconnected();//客户端断开
	void TcpServerSendData();//服务端发送数据
	void TcpServerSendAll();//服务端广播
	void ClearLog();
};


#include "QtGuiTcpServer.h"

QtGuiTcpServer::QtGuiTcpServer(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	connect(ui.btn_open, &QPushButton::clicked, this, &QtGuiTcpServer::btn_Open_Clicked);
	connect(ui.pushButton, &QPushButton::clicked, this, &QtGuiTcpServer::TcpServerSendData);
	connect(ui.pushButton_2, &QPushButton::clicked, this, &QtGuiTcpServer::TcpServerSendAll);
	connect(ui.pushButton_3, &QPushButton::clicked, this, &QtGuiTcpServer::ClearLog);
}

QtGuiTcpServer::~QtGuiTcpServer(void)
{
	for (int i = 0; i < m_Sockets.count(); i++)//断开任何信号与任何槽的关联
	{
		m_Sockets.values()[i]->disconnectFromHost();//掐断所有客户端连接
		i--;
	}
}

//开启服务端
void QtGuiTcpServer::btn_Open_Clicked(void)
{
	QString btnName = ui.btn_open->text();
	if (btnName == "打开")
	{
		if (m_TcpServer == NULL)
		{
			m_TcpServer = new QTcpServer(this);
		}
		ui.btn_open->setText("关闭");
		m_TcpServer->listen(QHostAddress::Any, ui.ledit_port->text().toUInt());//监听ipv4或ipv6地址	
		connect(m_TcpServer, SIGNAL(newConnection()), this, SLOT(ListenConnectRequst()));//监听
	}
	else
	{
		ui.btn_open->setText("打开");
		disconnect(m_TcpServer, nullptr, this, nullptr);//断开任何信号与任何槽的关联---槽函数绑定的次数为调用的次数
		for (int i = 0; i < m_Sockets.count(); i++)//断开任何信号与任何槽的关联
		{
			m_Sockets.values()[i]->disconnectFromHost();//掐断所有客户端连接
			i--;
		}
		m_TcpServer->close();//释放服务端
		AddLog("服务端已关闭!");
	}
}

//服务端发送数据
void QtGuiTcpServer::TcpServerSendData(void)
{
	QList<QListWidgetItem *> mItems = ui.listWidget_2->selectedItems();
	if (mItems.isEmpty())
	{
		QMessageBox::warning(this,"警告","请选中一行");
		return;
	}
	QString mSocketKey = mItems[0]->text();
	QTcpSocket *mSocket = m_Sockets.value(mSocketKey);
	QString mSendData = ui.textEdit->toPlainText();
	QByteArray mData = mSendData.toUtf8();
	mSocket->write(mData);
}

//服务端广播
void QtGuiTcpServer::TcpServerSendAll(void)
{
	for (int i=0;i<ui.listWidget_2->count();i++)
	{
		QString mSocketKey = ui.listWidget_2->item(i)->text();
		QTcpSocket *mSocket = m_Sockets.value(mSocketKey);
		QString mSendData = ui.textEdit->toPlainText();
		QByteArray mData = mSendData.toUtf8();
		mSocket->write(mData);
	}
}


//监听连接请求---槽函数--信号QTcpServer::newConnection
void QtGuiTcpServer::ListenConnectRequst(void)
{
	QTcpSocket *mSocket = m_TcpServer->nextPendingConnection();
	QString mSocketKey = mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort());
	AddLog(mSocketKey + "连接成功");
	if (!m_Sockets.contains(mSocketKey))
	{
		m_Sockets.insert(mSocketKey,mSocket);//将新客户端添加入集合
		ui.listWidget_2->addItem(mSocketKey);
		connect(mSocket, &QTcpSocket::readyRead, this, &QtGuiTcpServer::TcpServerReadData);//读取数据信号与槽
		connect(mSocket, &QTcpSocket::disconnected, this, &QtGuiTcpServer::TcpClientDisconnected);//客户端断开时信号与槽
	}
}

//读取数据
void QtGuiTcpServer::TcpServerReadData(void)
{
	QTcpSocket *mSocket = qobject_cast<QTcpSocket *>(sender());//获取信号发起者
	QByteArray mData = mSocket->readAll();
	AddLog(mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort()) + " = " + mData);//显示读取到的信息
}

//客户端断开
void QtGuiTcpServer::TcpClientDisconnected(void)
{
	QTcpSocket *mSocket = qobject_cast<QTcpSocket *>(sender());//获取信号发起者
	QString mSocketKey = mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort());
	AddLog(mSocketKey + "断开连接");//显示读取到的信息
	disconnect(mSocket, nullptr, this, nullptr);//断开任何信号与任何槽的关联
	m_Sockets.remove(mSocketKey);//将之从集合中删除
	for (int i=0;i<ui.listWidget_2->count();i++)
	{
		QString mStr = ui.listWidget_2->item(i)->text();
		if (mStr == mSocketKey)
		{
			ui.listWidget_2->takeItem(i);
			break;
		}
	}
	mSocket->close();
}


//添加日志
void QtGuiTcpServer::AddLog(QString mStr)
{
	if (ui.listWidget->count() > 100)
	{
		ui.listWidget->takeItem(98);//删除98行
	}
	ui.listWidget->insertItem(0, QDateTime::currentDateTime()
		.toString("HH:mm:ss zzz") + " -> " + mStr);
}
void QtGuiTcpServer::ClearLog(void)
{
	ui.listWidget->clear();
}

在这里插入图片描述

3.客户端代码

#include <QtWidgets/QMainWindow>
#include "ui_QtGuiTcpClient.h"
#include <QPushButton>
#include <QTcpSocket>
#include <QNetworkInterface>
#include <QDateTime>
#include <QThread>

class QtGuiTcpClient : public QMainWindow
{
	Q_OBJECT

public:
	QtGuiTcpClient(QWidget *parent = Q_NULLPTR);

private:
	Ui::QtGuiTcpClientClass ui;
	QTcpSocket *m_Socket;
	void AddLog(QString mStr);//添加日志

	private slots:
	void GetHostIPAdress();//获取本地ip地址
	void TcpClientConnectServer();//连接服务端
	void TcpClientDisconnServer();//断开服务端
	void TcpClientReadData();//接收数据
	void TcpClientSendData();//发送数据
	void ClearText();//清空日志
};
#include "QtGuiTcpClient.h"

QtGuiTcpClient::QtGuiTcpClient(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	connect(ui.pushButton, &QPushButton::clicked, this, &QtGuiTcpClient::GetHostIPAdress);
	connect(ui.pushButton_2, &QPushButton::clicked, this, &QtGuiTcpClient::TcpClientConnectServer);
	connect(ui.pushButton_3, &QPushButton::clicked, this, &QtGuiTcpClient::TcpClientSendData);
	connect(ui.pushButton_4, &QPushButton::clicked, this, &QtGuiTcpClient::ClearText);
}


//获取本地ip地址
void QtGuiTcpClient::GetHostIPAdress(void)
{
	QString mIpAddress;
	QList<QHostAddress> mIpAddressesList = QNetworkInterface::allAddresses();
	for (int i = 0; i < mIpAddressesList.size(); ++i)
	{
		if (mIpAddressesList.at(i) != QHostAddress::LocalHost &&  mIpAddressesList.at(i).toIPv4Address())
		{
			mIpAddress = mIpAddressesList.at(i).toString();
		}
	}
	if (mIpAddress.isEmpty())
	{
		mIpAddress = QHostAddress(QHostAddress::LocalHost).toString();
	}	
	ui.lineEdit_2->setText(mIpAddress);
}

//连接服务端
void QtGuiTcpClient::TcpClientConnectServer(void)
{
	QString mStr = ui.pushButton_2->text();

	if (mStr == "连接")
	{
		m_Socket = new QTcpSocket;
		ui.pushButton_2->setText("断开");
		//获取服务器ip和端口
		QString mIp = ui.lineEdit_2->text();
		qint16 mPort = ui.lineEdit->text().toUInt();

		//主动和服务器建立连接
		m_Socket->connectToHost(QHostAddress(mIp), mPort);
		connect(m_Socket, &QTcpSocket::readyRead, this, &QtGuiTcpClient::TcpClientReadData);//读取数据信号与槽
		connect(m_Socket, &QTcpSocket::disconnected, this, &QtGuiTcpClient::TcpClientDisconnServer);//客户端断开时信号与槽
		AddLog("连接成功!");
	}
	else
	{
		m_Socket->disconnectFromHost();
		m_Socket->close();
		ui.pushButton_2->setText("连接");
	}
}

//断开服务端
void QtGuiTcpClient::TcpClientDisconnServer(void)
{
	QTcpSocket *mSocket = qobject_cast<QTcpSocket *>(sender());//获取信号发起者
	QString mSocketKey = mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort());
	AddLog(mSocketKey + "断开连接");//显示读取到的信息
	disconnect(mSocket, nullptr, this, nullptr);//断开任何信号与任何槽的关联
	mSocket->close();
	ui.pushButton_2->setText("连接");
}

//接收数据
void QtGuiTcpClient::TcpClientReadData(void)
{
	QTcpSocket *mSocket = qobject_cast<QTcpSocket *>(sender());//获取信号发起者
	QByteArray mData = mSocket->readAll();
	AddLog(mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort()) + " = " + mData);//显示读取到的信息
}

//添加日志
void QtGuiTcpClient::AddLog(QString mStr)
{
	if (ui.listWidget->count() > 100)
	{
		ui.listWidget->takeItem(98);//删除98行
	}
	ui.listWidget->insertItem(0, QDateTime::currentDateTime()
		.toString("HH:mm:ss zzz") + " -> " + mStr);
}

//服务端发送数据
void QtGuiTcpClient::TcpClientSendData(void)
{
	QString mSendData = ui.lineEdit_3->text();
	QByteArray mData = mSendData.toUtf8();
	m_Socket->write(mData);
}

//清除日志
void QtGuiTcpClient::ClearText(void)
{
	ui.listWidget->clear();
}

在这里插入图片描述

4.多客端端与服务端通信测试

在这里插入图片描述

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱搞事的程小猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值