Qt系列文章013-TCP通信
1 前言
在前面讲完Qt的辅助网络请求类后,今天开始正式进入实践常用的网络通信方式——TCP通信, 这章主要讲解TCP通信的含义和Qt相关的Tcp类库详解,具体实践程序设计讲解放到下一章,本章主打基础知识讲解!
2 TCP概述
TCP(Transmission Control Protocol) 是一种 被大多数Internet网络协议(如HTTP和FTP)用于数据传输的低级网络协议,它是可靠的、面向流、面向连接的传输协议,特别适合用于连续数据传输。
TCP通信必须先建立TCP连接,通信端分为客户端和服务器端,通信原理三次握手(如下图所示)。
3 QTcp 类介绍
Qt 提供QTcpSocket类和QTcpServer类用于建立TCP通信应用程序。服务器端程序必须使用QTcpServer用于端口监听,建立服务器;QTcpSocket用于建立连接后使用套接字(Socket)进行通信。
QTcpServer是从QObject继承的类,它主要用于服务器端建立网络监听,创建网络Socket连接。QTepServer类的主要接口函数见下表:
类型 | 函数 | 功能描述 |
---|---|---|
公共函数 | void close() | 关闭服务器,停止网络监听 |
公共函数 | void errorString(() | 返回最近发生的错误描述 |
公共函数 | bool listen() | 在给定IP地址和端口.上开始监听,若成功就返回true |
公共函数 | bool isListening() | 返回true表示服务器处于监听状态 |
公共函数 | QTcpSocket * nextPendingConnection() | 返回下一个等待接入的连接 |
公共函数 | QHostAddress serverAddress() | 如果服务器处于监听状态,返回服务器地址 |
公共函数 | quint16 serverPort() | 如果服务器处于监听状态,返回服务器监听端口 |
公共函数 | bool waitForNewConnection() | 以阻塞方式等待新的连接 |
信号 | void acceptError(QAbstractSocket:SocketError) | 当接受一个新的连接发生错误时发射此信号,参数socketError描述了错误信息 |
信号 | void newConnection() | 当有新的连接时发射此信号 |
保护函数 | void incomingConnection(qintptr socketDescriptor) | 当有一个新的连接可用时,QTcpServer内部调用此函数,创建一个QTcpSocket对象,添加到内部可用新连接列表,然后发射newConnection()信号。用户若从QTcpServer继承定义类,可以重定义此函数,但必须调用addPendingConnection() |
保护函数 | void addPendingConnection(QTcpSocket*socket) | 由incomingConnection()调用,将创建的QTcpSocket添加到内部新可用连接列表 |
服务器端程序首先需要用 QTcpServer:listen() 开始服务器端监听,可以指定监听的IP地址和端口,一般一个服务程序只监听某个端口的网络连接。
当有新的客户端接入时,QTcpServer内部的incomingConnection()函数会创建一一个 与客户端连接的QTcpSocket对象,然后发射信号newConnection()。 在newConnection()信号的槽函数中,可以用nextPendingConnection()接受客户端的连接,然后使用QTcpSocket与客户端通信。
所以在客户端与服务器建立TCP连接后,具体的数据通信是通过QTcpSocket完成的。
QTcpSocket类提供了TCP协议的接口,可以用QTcpSocket类实现标准的网络通信协议如POP3、SMTP和NNTP,也可以设计自定义协议。
QTcpSocket是从QIODevice间接继承的类,所以具有流读写的功能。QTcpSocket和下一节要讲到的QUdpSocket的类继承关系如下图所示。
QTcpSocket类除了构造函数和析构函数,其他函数都是从QAbstractSocket继承或重定义的。QAbstractSocket用于TCP通信的主要接口函数见下表:
类型 | 函数 | 功能描述 |
---|---|---|
公共函数 | connectToHost(const QHostAddress &address, quint16 port, QIODevice::OpenMode openMode = ReadWrite) | 以异步方式连接到指定IP地址和端口的TCP服务器,连接成功后会发射connected(信号 |
公共函数 | void disconnectF romHost() | 断开socket,关闭成功后发射disconnected()信号 |
公共函数 | bool waitForConnected() | 等待直到建立socket连接 |
公共函数 | bool waitForDisconnected() | 等待直到断开socket连接 |
公共函数 | QHostAddress localAddress() | 返回本socket的地址 |
公共函数 | quint16 localPort() | 返回本socket的端口 |
公共函数 | QHostAddress peerAddress() | 在已连接状态下,返回对方socket的地址 |
公共函数 | QString peerName() | 返回connectToHost()连接到的对方的主机名 |
公共函数 | quint16 peerPort() | 在已连接状态下,返回对方socket的端口 |
公共函数 | qint64 readBufferSize() | 返回内部读取缓冲区的大小,该大小决定了read()和 readAll()函数能读出的数据的大小 |
公共函数 | void setReadBufferSize(qint64 size) | 设置内部读取缓冲区大小 |
公共函数 | qint64 bytesAvailable() | 返回需要读取的缓冲区的数据的字节数 |
公共函数 | bool canReadLine() | 如果有行数据要从socket缓冲区读取,就返回true. |
公共函数 | SocketState state() | 返回socket当前的状态 |
信号 | void connected) | connectToHost()成功连接到服务器后发射此信号 |
信号 | void disconnected() | 当socket断开连接后发射此信号. |
信号 | void error(QAbstractSocket::SocketError socketError) | 当socket发生错误时发射此信号 |
信号 | void hostFound() | 调用connectToHost()找到主机后发射此信号 |
信号 | void stateChanged(QAbstractSocket::SocketState socketState) | 当socket的状态变化时发射此信号,参数socketState表示了socket当前的状态 |
信号 | void readyRead() | 当缓冲区有新数据需要读取时发射此信号,在此信号的槽函数里读取缓冲区的数据 |
4 调用交互
TCP客户端使用QTcpSocket与TCP服务器建立连接并通信。
客户端的QTcpSocket实例首先通过connectToHost()尝试连接到服务器,需要指定服务器的IP地址和端口。connectToHost()是异步方式连接服务器,不会阻塞程序运行,连接后发射connected(信号。
如果需要使用阻塞方式连接服务器,则使用waitForConnected()函数阻塞程序运行,直到连接成功或失败。例如:
socket->connectToHost("127.0.0.1",1340);
if (socket->waitForConnected(1000))
qDebug("Connected!");
与服务器端建立socket连接后,就可以向缓冲区写数据或从接收缓冲区读取数据,实现数据的通信。当缓冲区有新数据进入时,会发射readyRead0信号,一- 般在此信号的槽函数里读取缓冲区数据。
QTcpSocket是从QIODevice间接继承的,所以可以使用流数据读写功能。- - 个QTcpSocket
实例既可以接收数据也可以发送数据,且接收与发射是异步工作的,有各自的缓冲区。
作为演示TCP通信的实例,创建了一个TCPClient程序和一个TCPServer程序,两个程序的设计思路讲解放到下文具体详解。
总结:
TCPServer 程序具有如下的功能:
- 根据指定IP地址(本机地址)和端口打开网络监听,有客户端连接时创建socket连接;
- 采用基于行的数据通信协议,可以接收客户端发来的消息,也可以向客户端发送消息;
- 在状态栏显示服务器监听状态和socket的状态。
TCPClient程序具有如下的功能:
- 通过IP地址和端口号连接到服务器;
- 采用基于行的数据通信协议,与服务器端收发消息;
- 处理QTepSocket的StateChange()信号,在状态栏显示socket的状态。
相关文章
- Qt高级——QMake快速入门
- Qt小软件:LanFileSender(局域网文件传输小工具)
- qt tcpsocket_qt中udp通信
- TCP和UDP协议的区别_tcp和ip是什么意思
- C/C++ Qt 运用JSON解析库 [解析篇]
- tcp心跳包 - python TCP服务器v1.3 - 服务器抗压测试及关闭套接字处理
- linuxdeployqt-linux下Qt打包工具
- 获取Qt支持的所有字体
- Qt Qml 中动态创建 & 销毁视频容器技巧(二)
- 编程在Linux下学习Qt界面编程(linux下qt界面)
- Linux下Qt安装指南:快速部署Qt运行环境(linux下qt安装教程)
- Qt QComboBox下拉框及用法(详解版)
- Linux Qt共享库开发指南(linuxqt共享库)
- 使用Qt框架轻松连接MySQL数据库(qt与mysql连接)
- Linux 环境下运用 Qt 编程的秘籍(linux下的qt编程)
- Linux下QT实现摄像头程序开发(linuxqt摄像头)
- Qt在Linux下的强大开发体验(qt在linux开发)
- Qt下Linux系统的输入法研究(qt输入法linux)
- 实现Linux下Qt应用静态编译的方法(linux下qt静态编译)
- Linux Qt:快速下载指南(linuxqt下载)
- 开发linux下 Qt 图形界面开发实践(linux下qt图形界面)
- 数据库使用Qt连接Oracle数据库:一步一步实现(qt连接oracle)
- 简明易懂的Linux下QT安装指南(linux下安装qt教程)
- Adept Qt to Access Linux Commands(qt调用linux命令)
- 利用Qt轻松操作Oracle数据库(qt操作oracle)
- Linux系统中实现Qt串口通信的完美指南(qt串口通信linux)
- Linux 下NC命令TCP连接实例(linux nc tcp)
- QT如何访问MySQL数据库(qt访问mysql数据库)
- 使用TCP协议探测Redis连接状态(tcp查看redis连接)