QT序列化与网络传输

-什么是序列化

序列化是把实体对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。

反序列化是从有序字节流中重建对象,恢复对象状态。

-为什么需要序列化与反序列化

通过序列化将类对象以字节流形式在网络中进行传递和接收,简化了网络传输的代码编写。

-QT中的序列化

QDataStream实现了原生类型的序列化(QString、QMap、QHash等),对于自己定义的结构体或类,必须重载<<和>>操作符,通过对基本对象的序列化来实现所定义结构体或类的序列化。

之后使用QDataStream类对象的setDevice()方法将QDataStream和QTcpSocket绑定在一起,然后可以使用<<操作符写数据,使用>>操作符读数据。

-QT网络传输

重点介绍QTcpServer和QTcpSocket类,之后再接受QT实现网络传输的几种方式。

QTcpServer使得监听并接收TCP连接成为可能,你可以在特定网络地址的特定端口监听所有TCP连接。一般来讲我们自己的服务器类需要继承QTcpServer类并覆写它的incomingConnection(qint socketDescriptor)方法。

重点介绍一下incomingConnection方法,该方法是个虚方法,当有新连接可用时该方法被QTcpServer自动调用,socketDescriptor参数是接受的连接的本机套接字描述符。

在基类中该方法会创建一个QTcpSocket对象,设置它的socketDescriptor参数并把它存在待处理连接列表中,然后发射newConnection()信号,使用自己写的槽函数接收该信号,在槽函数中使用hasPendingConnections判断是否有待处理的连接,使用nextPendingConnection得到一个连接。

值得注意的是该方法在基类中的实现得到的QTcpSocket对象不能用于另一个线程,若要使用多线程实现网络处理必须覆写该方法。

总的来说,直接在该方法中创建套接字对象而不使用多线程的方法处理网络连接,最重要的一点就是需要使用addPendingConnection()方法把该对象添加到未处理连接列表中。

若要使用多线程处理网络连接,则必须将socketDescriptor参数传入新线程中,在新线程里创建QTcpSocket对象并使用setSocketDescriptor()方法设置其套接字描述符。

-Qt使用QTcpServer和QTcpSocket实现tcp的通信

服务端

1.创建QTcpServer对象server.

2.server启动监听listen();

3.将自己的槽函数连接到server的newConnection信号,服务端接收到新的连接触发该信号,槽函数收到该信号后将处理该连接。(根据情况这一步可放在第2步前)

4.在第三步连接的槽函数中获取sever创建的QTcpSocket对象。QTcpSocket* socket = server->nextPendingConnection();

5.使用socket与客户端通信。(连接socket的readRead信号,在对应的槽函数中获取接收到的数据;使用write函数发送数据)

除了上述方法外,还有一种方法:

1. 新建一个类,继承至QTcpServer。

2. 重写void incomingConnection(qintptr socketDescriptor)函数。

3. 在incomingConnection中创建一个新的线程对象并传入socketDescriptor参数,在新线程中创建QTcpSocket对象并用setSocketDescriptor方法设置该套接字对象的描述符。

4.使用套接字与客户端通信。

-序列化与网络传输

通过序列化的方法可以方便的在网络上传输对象。

覆写QDataStream类的<<和>>方法实现序列化,使用setDevice方法把QDataStream类对象绑定到QTcpSocket对象上就可以方便的使用<<和>>方法进行网络数据的写入与读取。

//将QDataStreamQTcpSocket绑定,QTcpSocket是一种QIODevice,代表了一种网络输入输出设备
//tcpSocket的打开模式是ReadWrite,所以stream既可以读也可以写
QDataStream stream(&tcpSocket);
stream.setVersion(QDataStream::Qt_4_0);
stream << tcpData;//通过<<运算符直接将tcpData写入out连接的套接字中

你可能也喜欢

0 0 vote
Article Rating
Subscribe
提醒
0 评论
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
Scroll to Top