Qt TCP 簡單通訊

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();

客戶端app

  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();

代碼

服務器代碼
.hsocket

#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;						// 保存和全部客戶端通訊的套接字	
};

.cpptcp

#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;
};

.cppui

#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/13689602this

相關文章
相關標籤/搜索