咸鱼DoYoung  
做一条有理想的咸鱼

Qt TCP通信 例子

效果

流程

通信分为服务器客户端
服务器

  1. 实例化一个服务器对象
pServer = new QTcpServer;
  1. 关联服务器的newConnection信号,当有新的客户端连接时,会发送该信号
connect(pServer, &QTcpServer::newConnection, this, &TCP::slo_newConnection);
  1. 启动监听
pServer->listen(QHostAddress("127.0.0.1"), 8848);
  1. 当有客户端建立连接时,在关联newConnection信号,对应的槽函数中获取与对应客户端通信的套接字对象
// 获取与客户端通信的套接字对象
QTcpSocket * tcpSocket = pServer->nextPendingConnection();
  1. 关联套接字的readyRead信号,接收客户端信息,关联套接字的disconnected信号,处理客户端断开连接
// 绑定信号 ,接收客户端消息
connect(tcpSocket, &QTcpSocket::readyRead, this, &TCP::slo_readMsg);
// 客户端断开连接
connect(tcpSocket, &QTcpSocket::disconnected,this,&TCP::slo_clientDisConn);
  1. 向所有客户端发送消息
// 遍历所有客户端套接字
for (auto socket : mSokets)
{
      socket->write(ui->lineEdit_3->text().toUtf8());
}
  1. 关闭监听,直接close()
pServer->close();

客户端

  1. 实例化与服务器通信的套接字对象
// 通信的套接字对象
pSokcet = new QTcpSocket(this);
  1. 关联套接字的readyRead信号,接收服务器信息
// 关联信号 ,接收服务端的消息
connect(pSokcet, &QTcpSocket::readyRead, this, &TCP_Client::slo_readMsg);
  1. 连接服务器
pSokcet->connectToHost(QHostAddress("127.0.0.1"), 8848);
  1. 向服务器发送消息
pSokcet->write(ui.lineEdit_3->text().toUtf8());
  1. 接收服务器消息
QString msg = QString::fromUtf8(pSokcet->readAll());
  1. 断开连接
pSokcet->close();

代码

服务器代码
.h

#pragma once

#include <QWidget>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>

namespace Ui { class TCP; };

class TCP : public QWidget
{
	Q_OBJECT

public:
	TCP(QWidget *parent = Q_NULLPTR);
	~TCP();

private slots:
	void slo_newConnection();						// 新客户端连接
	void slo_clientDisConn();						// 客户端断开连接
	void slo_listenerStart();						// 开启监听
	void slo_listenerStop();						// 关闭监听
	void slo_replyAll();							// 回复所有客户端
	void slo_readMsg();							// 接收客户端消息
private:
	void init();								// 初始化
	void updateMsg(const QString & msg);			                // 更新消息
	
private:
	Ui::TCP *ui;
	QTcpServer * pServer;							// 服务器对象
	QList<QTcpSocket*> mSokets;						// 保存和所有客户端通信的套接字	
};

.cpp

#include <QDateTime>
#include <QHostAddress>

#include "TCP.h"
#include "ui_TCP.h"

TCP::TCP(QWidget *parent)
	: QWidget(parent)
	,ui(new Ui::TCP())
{
	ui->setupUi(this);
	init();
}

TCP::~TCP()
{
	delete ui;
}

void TCP::slo_newConnection()
{
	// 获取与客户端通信的套接字对象
	QTcpSocket * tcpSocket = pServer->nextPendingConnection();
	// 绑定信号 ,接收客户端消息
	connect(tcpSocket, &QTcpSocket::readyRead, this, &TCP::slo_readMsg);
	// 客户端断开连接
	connect(tcpSocket, &QTcpSocket::disconnected,this,&TCP::slo_clientDisConn);
	// 保存套接字
	mSokets << tcpSocket;
	// 更新消息
	QString msg = QStringLiteral("新用户连接");
	updateMsg(msg);
}

void TCP::slo_clientDisConn()
{
	// 与客户端通信的套接字对象
		QTcpSocket * tcpSocket = qobject_cast<QTcpSocket*>(QObject::sender());
		// 移除
		mSokets.removeOne(tcpSocket);
		// 更新日志
		tcpSocket->disconnect(tcpSocket, 0, this, 0);

		QString msg = QStringLiteral("IP:%1的用户断开连接").arg(tcpSocket->peerAddress().toString());
		updateMsg(msg);

		tcpSocket->deleteLater();
}

void TCP::slo_listenerStart()
{
	if (pServer->isListening())
	{
		QString msg = QStringLiteral("监听已经打开,请先关闭当前监听");
		updateMsg(msg);
		return;
	}

	if (pServer->listen(QHostAddress(ui->lineEdit->text()), ui->lineEdit_2->text().toInt()))
	{
		QString msg = QStringLiteral("打开监听成功");
		msg += QStringLiteral(",监听IP::");
		msg += ui->lineEdit->text();
		msg += QStringLiteral(",监听Port:");
		msg += ui->lineEdit_2->text();
		updateMsg(msg);
	}
	else
	{
		updateMsg(QStringLiteral("打开监听失败"));
	}
}

void TCP::slo_listenerStop()
{
	if (pServer->isListening())
	{
		pServer->close();
		mSokets.clear();
		updateMsg(QStringLiteral("关闭监听成功"));
	}
	else
	{
		updateMsg(QStringLiteral("没有监听,不要重复关闭"));
	}
}

void TCP::slo_replyAll()
{
	if (mSokets.isEmpty())
	{
		updateMsg(QStringLiteral("还没有客户端连接"));
		return;
	}

	for (auto socket : mSokets)
	{
		socket->write(ui->lineEdit_3->text().toUtf8());
	}
}

void TCP::slo_readMsg()
{
	// 与客户端通信的套接字对象
	QTcpSocket * tcpSocket = qobject_cast<QTcpSocket*>(QObject::sender());
	// 接收消息
	QString msg = QString::fromUtf8(tcpSocket->readAll());
	// 显示 
	updateMsg(msg);
}

void TCP::init()
{
	// 初始化服务器对象
	pServer = new QTcpServer;
	// 关联newConnection信号,当有新的客户端连接时,会触发此信号
	connect(pServer, &QTcpServer::newConnection, this, &TCP::slo_newConnection);
}

void TCP::updateMsg(const QString & msg)
{
	QString string = QStringLiteral("【%1】").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
	string.append(msg);
	ui->textEdit->append(string);
}

客户端
.h

#pragma once

#include "ui_TCP_Client.h"

#include <QWidget>
#include <QtNetwork/QTcpSocket>
#include <QHostAddress>
#include <QString>

class TCP_Client : public QWidget
{
	Q_OBJECT

public:
	TCP_Client(QWidget *parent = Q_NULLPTR);
	~TCP_Client();
private slots:
	void slo_connectToHost();					// 接连
	void slo_disConnect();						// 断开接连
	void slo_sendMsg();						// 发送消息
	void slo_readMsg();						// 接收消息

private:										
	void init();							// 初始化
	void updateMsg(const QString& msg);			        // 更新消息
private:
	Ui::TCP_Client ui;
	QTcpSocket * pSokcet;
};

.cpp

#include "TCP_Client.h"

#include <QDateTime>

TCP_Client::TCP_Client(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	init();
}

TCP_Client::~TCP_Client()
{
}

void TCP_Client::slo_connectToHost()
{
	if (QTcpSocket::ConnectedState == pSokcet->state())
	{
		updateMsg(QStringLiteral("已经连接,不用重复连接"));
	}
	else if (QTcpSocket::UnconnectedState == pSokcet->state())
	{
		pSokcet->connectToHost(QHostAddress(ui.lineEdit->text()), ui.lineEdit_2->text().toInt());
		updateMsg(QStringLiteral("连接成功"));
	}
}

void TCP_Client::slo_disConnect()
{
	if (QTcpSocket::UnconnectedState == pSokcet->state())
	{
		updateMsg(QStringLiteral("未连接,不用重复断开"));
	}
	else if (QTcpSocket::ConnectedState == pSokcet->state())
	{
		pSokcet->close();
		updateMsg(QStringLiteral("已断开"));
	}
}

void TCP_Client::slo_sendMsg()
{
	pSokcet->write(ui.lineEdit_3->text().toUtf8());
}

void TCP_Client::slo_readMsg()
{
	// 套接字对象
	QString msg = QString::fromUtf8(pSokcet->readAll());
	// 显示 
	updateMsg(msg);
}

void TCP_Client::init()
{
	// 通信的套接字对象
	pSokcet = new QTcpSocket(this);
	// 关联信号 ,接收服务端的消息
	connect(pSokcet, &QTcpSocket::readyRead, this, &TCP_Client::slo_readMsg);
}

void TCP_Client::updateMsg(const QString& msg)
{
	QString string = QStringLiteral("【%1】").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
	string.append(msg);
	ui.textEdit->append(string);
}

源码下载

https://download.csdn.net/download/ShiShiSoLo/13689602

posted on 2020-12-14 23:08  咸鱼Doyoung  阅读(190)  评论(0编辑  收藏  举报