一、TCP特点
- 是可靠的、面向流、面向连接饿传输协议,适合用于连续数据传输
三次握手
服务端和客户端建立稳定的传输通道,需要3个步骤
- 客户端向服务器发送信息,发送一个报文(syn(请求同步))
- 服务端将受到的客户端的报文重新发回去,再多加一个报文(ack(确认))
- 客户端再向服务端发送报文(ack)
四次挥手
服务端和客户端断开传输通断,需要4个步骤
- 客户端向服务端发送报文(fin(结束标志))
- 服务端收到这个报文,它回复一个报文(ack)
- 服务端关闭客户端连接
- 客户端发挥(ack)报文确认
TCP通信示意图
- 服务端程序使用QTcpServer用于端口监听,建立服务器
- QTcpSocket用于建立连接后使用套接字进行通信
QT中所需模块
QT +=network
二、QTcpServer
- 头文件:#include <QTcpServer>
- QTcpServer从QObject继承而来,主要用于服务器建立网络监听,创建网络Socket连接
主要函数与信号
- listen():服务端使用该函数开启监听。参数1的IP地址可以是“127.0.0.1”或本机的实际IP或常量QHostAddress::LocalHost
- incomingConnection():当有新的客户端接入时,该函数会创建一个与客户端连接的QTcpSocket对象,然后发射newConnection()信号。在newConnection()信号的糙汉书中,可以用nextPendingConnection()接受客户端的链接,然后使用QTcpSocket与客户端通信
三、QTcpSocket
- 头文件:#include <QTcpSocket>
- 客户端与服务器建立TCP连接后,具体的数据通信是通过QTcpSocket完成的。QTcpSocket提供了TCP协议的接口,可以使用QTcpSocket实现标准的网络通信协议如POP3、SMTP、NNTP
继承关系
- QTcpSocket从QIODevice间接继承而来,所以具有流读写的功能
主要函数与信号
- QTcpSocket除了构造函数和析构函数。其他函数都是从QAbstractSocket继承或重定义的。QAbstractSocket用于TCP通信的主要接口函数如下
- readyRead()信号:建立连接后,就可以向缓冲区读写数据,实现数据的通信,当缓冲区有新数据进入时,会发射readyRead()信号,一般在此信号的槽函数里读取缓冲区数据
- stateChanged()信号:当当前socket状态改变时,触发该信号,参数为socket的状态枚举类型,取值如下
补充:
//常用函数
abort(); //中止当前连接并重置套接字。与disconnectFromHost()不同,该函数立即关闭套接字,丢弃写缓冲区中的任何挂起数据
write(); //向外界发送数据。参数:发送的内容(const char*或QByteArray型)
readAll(); //读取外界传入的所有数据,返回值:QByteArray型
waitForBytesWritten(); //写入多久,才执行后面的语句。参数:写入时间(毫秒单位),默认为3秒
waitForReadyRead(); //读取多久,才执行后面的语句。参数:读取时间(毫秒单位),默认为3秒
errorString(); //返回错误信息
isValid(); //判断套接字是否有效
isOpen(); //判断套接字是否打开
flush(); //刷新数据区
deleteLater(); //断开连接之后,可以调用该函数在稍后删除本次会话的socket
//信号函数
bytesWritten(qint64); //向外界发送数据成功后相应,参数为发送的字节数
- setSocketOption()函数:设置socket的选项特性
阻塞连接与非阻塞连接
- connectToHost():客户端的QTcpSocket实例通过connectToHost尝试连接服务区,该方式是异步连接,不会阻塞程序运行,连接后发生connection()信号
- waitForConnected():如果需要使用阻塞方式连接服务器,则使用该函数,程序会一直阻塞直到连接成功或失败
四、数据的传输
读取方式
Socket之间的数据通信协议一般有两种方式:
- 基于行读:每次读一行
- 基于数据块读:一般用于二进制数据的传输,需要自定义具体的格式
canReadLine()函数
- 判断缓冲区中是否有一行数据可以读取,如果有,就调用readLine()函数读取一行的数据,例如:
如果基于二进制读:
数据的传输以QByteArray类型的形式传送(下面是QString与QByteArray类型的转换)
- QByteArray转QString:1.QString强转 2.QString静态方法fromLocal8Bit
- QString转QByteArray:1.QString函数:toUtf8(); 2.QString函数:toLocal8Bit()
基本函数
- 因为QTcpSocket是继承于QIODevice的,所以支持流的读写功能,也就支持流的读写函数
write(); //向外界发送数据
read(); //读取指定的数据
readLine(); //读取一行数据
readAll(); //读取外界传入的所有数据
五、演示案例
-