[QT编程系列-30]: 多进程机制 - QT Socket通信:QTcpSocket、QUdpSocket
目录
第1章 概述
1.1 概述
1.2 QT socket通信的本质
1.3 QUdpSocket相关的信号
1.4 QTcpSocket相关的信号
第2章 UDP通信示例
服务端代码:
客户端代码:
第3章 TCP通信代码示例
服务器端代码:
客户端代码:
第1章 概述
1.1 概述
在Qt中,通过套接字(socket)实现网络通信主要使用的是QTcpSocket和QUdpSocket类。QTcpSocket用于基于TCP协议的通信,而QUdpSocket用于基于UDP协议的通信。
在Qt中,使用TCP/IP协议进行网络通信可以使用QTcpSocket和QTcpServer类。QTcpServer用于创建服务器,监听连接请求并接受客户端连接,而QTcpSocket用于创建客户端,并与服务器建立连接。
1.2 QT socket通信的本质
QUdpSocket和QTcpSocket这两个类,是QT库提供的,应用程序,无论是服务器还是客户端,socket通信本质上就是创建应用程序的类和类对象,并且在socket库提供的QUdpSocket和QTcpSocket类和类对象之间进行对象间通信,当socket对象中有数据时,自动通过信号+槽机制,自动回调应用程序注册到socket对象中的槽函数。这就是QT socket通信的本质。
1.3 QUdpSocket相关的信号
QUdpSocket类在Qt中用于进行UDP网络通信。下面是QUdpSocket中一些常用的信号:
-
readyRead():当有新的数据可读取时触发该信号。可以通过调用readDatagram()方法读取数据。
-
stateChanged(QAbstractSocket::SocketState state):当QUdpSocket的状态发生变化时触发该信号。状态可以是QAbstractSocket::UnconnectedState(未连接状态)、QAbstractSocket::HostLookupState(主机查找状态)、QAbstractSocket::ConnectingState(连接中状态)、QAbstractSocket::ConnectedState(已连接状态)等。
-
errorOccurred(QAbstractSocket::SocketError socketError):当QUdpSocket发生错误时触发该信号。通过socketError参数可以获取到具体的错误类型,例如QAbstractSocket::ConnectionRefusedError(连接被拒绝错误)、QAbstractSocket::RemoteHostClosedError(远程主机关闭连接错误)等。
这些信号可以通过连接到相关的槽函数来实现相应的逻辑处理。使用示例如下:
// 声明QUdpSocket对象
QUdpSocket *udpSocket;
// 连接信号和槽函数
connect(udpSocket, &QUdpSocket::readyRead, this, &MyClass::readReady);
connect(udpSocket, &QUdpSocket::stateChanged, this, &MyClass::socketStateChanged);
connect(udpSocket, &QUdpSocket::errorOccurred, this, &MyClass::socketErrorOccurred);
// 槽函数实现
void MyClass::readReady()
{
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
QHostAddress senderAddress;
quint16 senderPort;
udpSocket->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort);
// 处理读取到的数据
}
void MyClass::socketStateChanged(QAbstractSocket::SocketState state)
{
// 处理状态变化
}
void MyClass::socketErrorOccurred(QAbstractSocket::SocketError socketError)
{
// 处理错误
}
通过连接这些信号和相应的槽函数,可以实现对QUdpSocket对象的事件响应和处理。
1.4 QTcpSocket相关的信号
在Qt中,使用QTcpSocket类进行TCP网络通信。下面是QTcpSocket类的一些常见信号:
-
connected():当TCP套接字成功连接到远程主机时发出的信号。
-
disconnected():当TCP套接字与远程主机断开连接时发出的信号。
-
readyRead():当有新的数据可供读取时发出的信号。可以通过调用read()方法读取数据。
-
bytesWritten(qint64 bytes):当已成功写入一定字节数的数据后发出的信号。可以通过bytes参数获取已写入的字节数。
-
hostFound():当QTcpSocket已成功查找到远程主机时发出的信号。
-
stateChanged(QAbstractSocket::SocketState state):当QTcpSocket的状态发生变化时发出的信号。状态可以是QAbstractSocket::UnconnectedState(未连接状态)、QAbstractSocket::HostLookupState(主机查找状态)、QAbstractSocket::ConnectingState(连接中状态)、QAbstractSocket::ConnectedState(已连接状态)等。
-
errorOccurred(QAbstractSocket::SocketError socketError):当QTcpSocket发生错误时发出的信号。通过socketError参数可以获取到具体的错误类型,例如QAbstractSocket::ConnectionRefusedError(连接被拒绝错误)、QAbstractSocket::RemoteHostClosedError(远程主机关闭连接错误)等。
这些信号可以通过连接到相关的槽函数来实现相应的逻辑处理。使用示例如下:
// 声明QTcpSocket对象
QTcpSocket *tcpSocket;
// 连接信号和槽函数
connect(tcpSocket, &QTcpSocket::connected, this, &MyClass::socketConnected);
connect(tcpSocket, &QTcpSocket::disconnected, this, &MyClass::socketDisconnected);
connect(tcpSocket, &QTcpSocket::readyRead, this, &MyClass::socketReadyRead);
connect(tcpSocket, &QTcpSocket::bytesWritten, this, &MyClass::bytesWritten);
connect(tcpSocket, &QTcpSocket::hostFound, this, &MyClass::hostFound);
connect(tcpSocket, &QTcpSocket::stateChanged, this, &MyClass::socketStateChanged);
connect(tcpSocket, &QTcpSocket::errorOccurred, this, &MyClass::socketErrorOccurred);
// 槽函数实现
void MyClass::socketConnected()
{
// 处理连接成功事件
}
void MyClass::socketDisconnected()
{
// 处理断开连接事件
}
void MyClass::socketReadyRead()
{
// 处理有数据可读事件
}
void MyClass::bytesWritten(qint64 bytes)
{
// 处理数据写入事件
}
void MyClass::hostFound()
{
// 处理主机查找事件
}
void MyClass::socketStateChanged(QAbstractSocket::SocketState state)
{
// 处理状态变化
}
void MyClass::socketErrorOccurred(QAbstractSocket::SocketError socketError)
{
// 处理错误
}
通过连接这些信号和相应的槽函数,可以实现对QTcpSocket对象的事件响应和处理。
第2章 UDP通信示例
下面是一个简单的示例代码,展示了如何使用Qt进行UDP通信:
服务端代码:
// Server.h
#ifndef SERVER_H
#define SERVER_H
#include
#include
class Server : public QObject
{
Q_OBJECT
public:
explicit Server(QObject *parent = nullptr);
public slots:
void readyRead();
private:
QUdpSocket *udpSocket;
};
// Server.cpp
#include "Server.h"
Server::Server(QObject *parent) : QObject(parent)
{
//创建udp socket对象
udpSocket = new QUdpSocket(this);
//由于是服务器,需要绑定socket的IP地址和端口号
udpSocket->bind(QHostAddress::Any, 12345);
//在socket对象和Server应用程序之间建立信号与回调函数机制
//当Server中有数据时,socket自动发送信号给Server应用程序,自动调用Server注册到Socket中的回调函数
connect(udpSocket, &QUdpSocket::readyRead, this, &Server::readyRead);
}
// Server的应用程序
void Server::readyRead()
{
while (udpSocket->hasPendingDatagrams()) {
//为读取/接收数据准备缓冲区
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
//为获取发送方信息准备对象
QHostAddress senderAddress;
quint16 senderPort;
//应用程序从socket中读取数据
udpSocket->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort);
qDebug() 