Qt 中的TCP协议通信

TCP协议是经常使用的通信方式。在QT中做了非常友好的封装,使用非常方便。
需要添加的模块:network
Qt中的TCP类:QTcpSocket , QTcpServer

常用函数介绍

连接目标地址和端口
virtual void QTcpSocket ::connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);

  • 发送数据
    inline qint64 QTcpSocket ::write(const QByteArray &data)

  • 监听某个地址和端口号
    bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);

  • 有新的连接信号
    void QTcpServer::newConnection();

  • 是否有新的连接
    virtual bool QTcpServer::hasPendingConnections() const;

  • 获取新的连接,必须处理完才能继续接收到连接
    virtual QTcpSocket *QTcpServer::nextPendingConnection();

  • 收到新的数据信号
    void QTcpSocket::readyRead();

  • 读取收到的数据,必须读取完才能继续接收
    QByteArray readAll();

使用案例(example)

  • 客户端
#include <QTcpSocket>
#include <QWidget>
#include <QLineEdit>
class Client : public QWidget
{
	Q_OBJECT
public:
	Client(QWidget *parent);

public slots:
	void slotSendButtonClick();
private:
	QTcpSocket *_socket;
	QLineEdit *_lineEdit;
	bool _isConnected;
};


#include "client.h"
#include <QPushButton>
#include <QHBoxLayout>
Client::Client(QWidget *parent)
	: QWidget(parent)
{
	_socket = new QTcpSocket(this);

	_lineEdit = new QLineEdit(this);
	QPushButton *sendButton = new QPushButton("send");
	connect(sendButton, SIGNAL(clicked()), this, SLOT(slotSendButtonClick()));
	connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(slotSendButtonClick()));
	
	QHBoxLayout *lay = new QHBoxLayout(this);
	lay->addWidget(_lineEdit);
	lay->addWidget(sendButton);

	_isConnected = false;
}

void Client::slotSendButtonClick()
{
	if (!_isConnected)
	{
		_socket->connectToHost("127.0.0.1", 9988);
		_isConnected = true;
	}
	QString text = _lineEdit->text();
	if (!text.isEmpty())
	{
		_socket->write(text.toUtf8());//发送数据
		_lineEdit->clear();
	}
}


  • 服务端
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
class QTextBrowser;
class Server :public QWidget
{
	Q_OBJECT
public:
	Server(QWidget *parent);
public slots:
	void slotCurrentIndexChanged(const QString&);
	void slotNewConnection();
private:
	QTcpServer *_server;
	QTcpSocket *_socket;
	QTextBrowser *_textBrowser;
};


#include "server.h"
#include <QHostAddress>
#include <QTextBrowser>
#include <QByteArray>
#include <QGridLayout>
#include <QNetworkInterface>
#include <QComboBox>
Server::Server(QWidget *parent)
{
	_server = new QTcpServer(this);
	//_server->listen(QHostAddress::Any, 9988);//监听跟本主机相连的所有网口
	connect(_server, SIGNAL(newConnection()),this, SLOT(slotNewConnection()) );

	QList<QHostAddress> addrList = QNetworkInterface::allAddresses();
	QComboBox *comboBox = new QComboBox;
	for (const QHostAddress& addr : addrList)
	{
		quint32 ipAddr = addr.toIPv4Address();
		if (ipAddr != 0)
		{
			comboBox->addItem(QHostAddress(ipAddr).toString());
		}
	}
	connect(comboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotCurrentIndexChanged(const QString&)));


	_textBrowser = new QTextBrowser(this);
	QGridLayout *lay = new QGridLayout(this);
	lay->addWidget(comboBox, 0, 0);
	lay->addWidget(_textBrowser,1,0);
}

void Server::slotCurrentIndexChanged(const QString& item)
{
	if (!_server->isListening())
	{
		_server->listen(QHostAddress(item), 9988);
	}
	
	_textBrowser->append("listen...");
}

void Server::slotNewConnection()
{
	_textBrowser->append("connecting...");
	while (_server->hasPendingConnections())//必须处理完所有的连接,否则有新连接时就不会在发信号过来
	{
		_socket = _server->nextPendingConnection();
		connect(_socket, &QTcpSocket::readyRead, [&]() {
			_textBrowser->append("receive message...");
			QByteArray newMessage = _socket->readAll();
			_textBrowser->append(QString(newMessage));
		});
	}
}


使用效果

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值