TCP(Transmission Control Protocol)是一种被大多数网络协议用于数据传输的低级网络协议,它是可靠的、面向流、面向连接的传输协议,特别适合用于连续数据传输。
TCP通信必须先建立TCP连接,通信端分为客户端和服务器端。Qt提供QTcpSocket类和QTcpServer类用于建立TCP通信应用程序。服务器端程序使用QTcpServer用于端口监听,建立服务器;QTcpSocket用于建立连接后使用套接字Socket进行通信。
一 QTcpServer类主要接口函数
1 公共函数
| 函数 | 功能 |
|---|---|
| void close() | 关闭服务器,停止网络监听 |
| bool listen() | 在给定IP地址和端口上开始监听,成功返回true |
| bool isListening() | 返回true标识服务器处于监听状态 |
| QTcpSocket *nextPendingConnection() | 返回下一个等待接入的连接 |
| QHostAddress serverAddress() | 如果服务器处于监听状态,返回服务器地址 |
| quint16 serverPort() | 如果服务器处于监听状态,返回服务器监听端口 |
| bool waitForNewConnection() | 以阻塞方式等待新的连接 |
2 信号
| 函数 | 功能 |
|---|---|
| void newConnection() | 当有新的连接时发射此信号 |
| void acceptError(QAbstractSocket::SocketError socketError) | 当接受一个新的连接发生错误时发射此信号,参数socketError描述了错误信息 |
3 保护函数
| 函数 | 功能 |
|---|---|
| void incomingConnection(qintptr socketDescriptor) | 当有一个新的连接可用时,QTcpServer内部调用此函数,创建一个QTcpSocket对象,添加到内部可用新连接列表,然后发射newConnection() 信号。用户若从Q TcpServer继承定义类,可以重定义此函数,但必须调用addPendingConnection() |
| void addPendingConnection(QTcpSocket *socket) | 由incomingConnection() 调用, 将创建的QTcpSocket添加到内部新可用连接列表 |
服务器端程序首先需要用QTcpServer::listen()开始服务器端监听,可以指定监听的IP和端口。当有新的客户端接入时,QTcpServer内部的incomingConnection()函数会创建一个与客户端连接的QTcpSocket对象,然后发射信号newConnection()。在newConnection()信号的槽函数中,可以用nextPendingConnection()接受客户端的连接,然后使用QTcpSocket与客户端通信。
二 QTcpSocket类主要接口函数(继承于QAbstractSocket)
1 公共函数
| 函数 | 功能 |
|---|---|
| void connectToHost(QHostAddress &address, quint16 port) | 以异步方式连接到指定IP地址和端口的TCP服务器,连接成功后会发射connected() 信号 |
| void disconnectFromHost() | 断开socket,关闭成功后发射disconnected() 信号 |
| bool waitForConnected() | 等待直到建立socket连接 |
| bool waitForDisconnected() | 等待直到断开socket连接 |
| QHostAddress localAddress() | 返回本socket的地址 |
| quint16 localPort() | 返回本socket的端口 |
| QHostAddress peerAddress() | 在已连接状态下,返回对方socket的地址 |
| quint16 peerPort() | 在已连接状态下, 返回对方socket的端口 |
| QString peerName() | 返回connectToHost() 连接到的对方的主机名 |
| qint64 readBufferSize() | 返回内部读取缓冲区的大小,该大小决定了read() 和readAll()函数能读出的数据的大小 |
| void setReadBufferSize(qint64 size) | 设置内部读取缓冲区大小 |
| qint64 bytesAvailable() | 返回需要读取的缓冲区的数据的字节数 |
| bool canReadLine() | 如果有行数据要从socket缓冲区读取, 就返回true |
| SocketState state() | 返回socket当前的状态 |
2 信号
| 函数 | 功能 |
|---|---|
| void connected() | connectToHost() 成功连接到服务器后发射此信号 |
| void disconnected() | 当socket断开连接后发射此信号 |
| void error(QAbstractSocket::SocketError socketError) | 当socket发生错误时发射此信号 |
| void hostFound() | 调用connectToHost() 找到主机后发射此信号 |
| stateChanged(QAbstractSocket::SocketState socketState) | 当socket的状态变化时发射此信号,参数socketStat表示了socket当前的状态 |
| void readyRead() | 当缓冲区有新数据需要读取时发射此信号,在此信号的槽函数里读取缓冲区的数据 |
客户端的QTcpSocket实例首先通过connectToHost()尝试连接到服务器,连接后发射connected()信号(可以使用waitForConnected()函数阻塞程序运行,直到连接成功或失败)。与服务器端建立socket连接后,就可以向缓冲区写数据或从接收缓冲区读取数据,实现数据的通信。当缓冲区有新数据进入时,会发射readyRead()信号,一般在此信号的槽函数里读取缓冲区数据。
学习书籍:《Qt5.9 C++开发指南》