>

在标准C++没有提供专门用于套接字通信的类,所以只能使用操作系统提供的基于C的API函数,基于这些C的API函数我们也可以封装自己的C++类 C++套接字类的封装。但是Qt就不一样了,它是C++的一个框架并且里边提供了用于套接字通信的类(TCP、UDP)这样就使得我们的操作变得更加简单了(当然,在Qt中使用标准C的API进行套接字通信也是完全没有问题的)。下面,给大家讲一下使用相关类的进行TCP通信(关于TCP的更详细介绍在此不做展开)。

使用Qt提供的类进行基于TCP的套接字通信需要用到两个类:

QTcpServer服务器类,用于监听客户端连接以及和客户端建立连接。
QTcpSocket通信的套接字类,客户端、服务器端都需要使用。
这两个套接字通信类都属于网络模块network。在QT里我们如果想要使用这两个类,需要在项目的.pro或者是CMakeLists.txt文件里做如下操作(在QtCreator的帮助文档里都能找得到的):

CMake: find_package(Qt6 REQUIRED COMPONENTS Network)
target_link_libraries(mytarget PRIVATE Qt6::Network)
qmake: QT += network

接下来我将介绍一下这两个类里的一些API函数。

1.QTcpServer

QTcpServer是服务器类,主要的作用是监听和连接客户端。

1.1公共函数

构造函数: QTcpServer::QTcpServer(QObject *parent = nullptr)

监听函数:bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0) 用于服务器监听来自地址和端口连接信号,其返回值为bool类型,参数一是ip地址,参数而是端口号。如果参数一是Any,那么服务器会监听所有address的连接信号。参数二port=0时是代表自动选择端口监听成功返回true,反之false。

判断是否正在监听: bool QTcpServer::isListening() const

获取服务器地址:QHostAddress QTcpServer::serverAddress() const 如果当前服务器正在监听返回服务器地址,反之返回QHostAddress::Null。

获取服务器端口:quint16 QTcpServer::serverPort() const如果当前服务器正在监听返回服务器端口值,否则返回0。

得到和客户端建立连接之后的套接字对象:QTcpSocket *QTcpServer::nextPendingConnection()得到的对象是QTcpServer的一个子对象,QTcpServer析构时会自动析构这个子对象,当然也可以自己手动析构这个子对象。

阻塞等待客户端发起的连接请求:bool QTcpServer::waitForNewConnection(int msec = 0, bool *timedOut = nullptr)参数一为阻塞最大时长,参数二timeout判断是否超时。此函数不太适合于在单线程里使用,比他更合适于处理新连接的是信号newConnection()

1.2信号

void QTcpServer::newConnection()这是新连接信号,每次新建连接都会发送此信号。

void QTcpServer::acceptError(QAbstractSocket::SocketError socketError)新连接出现错误会释放此信号,socketError参数会描述此错误。

2.QTcpSocket

QTcpSocket是一个套接字通信类,在服务器和客户端都会使用。Qt里的收发数据也属于IO操作(网络IO)

QTcpSocket继承了QAbstractSocket,后者又继承了QIODevice。

1.1成员函数

构造函数: QTcpSocket::QTcpSocket(QObject *parent = nullptr)

连接服务器(需指定端口号与IP地址):

[virtual] void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, QIODeviceBase::OpenMode openMode = ReadWrite, QAbstractSocket::NetworkLayerProtocol protocol = AnyIPProtocol)

void QAbstractSocket::connectToHost(const QHostAddress &address, quint16 port, QIODeviceBase::OpenMode openMode = ReadWrite)

在Qt中不管调用读操作函数接收数据,还是调用写函数发送数据,操作的对象都是本地的由Qt框架维护的一块内存。因此,调用了发送函数数据不一定会马上被发送到网络中,调用了接收函数也不是直接从网络中接收数据,有缓冲区。关于底层的相关操作是不需要使用者来维护的。

接收数据

QByteArray QIODevice::read(qint64 maxSize) 指定可接收最大字节数,返回接收的字符串

qint64 QIODevice::read(char *data, qint64 maxSize)指定可接收最大字节数,maxSize指针指向data

QByteArray QIODevice::readAll() 读出当前所有可操作数据,以byte array的形式返回

发送数据

qint64 QIODevice::write(const char *data, qint64 maxSize)发送指针data指向内存里大小为maxSize的数据

qint64 QIODevice::write(const char *data)发送指针data指向内存里的数据,字符串以\0为标记

qint64 QIODevice::write(const char *data)发送指定字符串

2.2信号

void QIODevice::readyRead()表示对端数据发送成功,可以准备接收数据调用read函数

void QAbstractSocket::connected()调用connectToHost()函数并成功连接之后会发出该信号。

void QAbstractSocket::disconnected()套接字断开连接之后发出的信号

以上就是这两个类的一些基本API函数和信号。其实这里面的API函数很多,我无法面面俱到,只能提一下基础的。大家使用时可以直接查QtCreator里的帮助文档。

关于这些类在项目里的实战应用,我将在后面的文章里继续提。

水平有限,有错误之处多多包涵!

Categories:

Tags:

No responses yet

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注

    近期评论

    2026 年 4 月
     12345
    6789101112
    13141516171819
    20212223242526
    27282930 
    苏ICP备2026009218号-1 苏公网安备32120002120009号