QT网络编程:服务端和客户端编程

QtNetwork中的QTcpSocket和QTcpServer类可用來编写基于TCP的client和server

 

QTcpSocket提供client端的TCP功能,能够发出TCP的请求至服务器,其实它也是具有服务端发送数据到客户端的功能

QTcpServer则提供服务器的功能,并接受TCP连接请求,以及指定port或IP位址

 

一、客户端的请求与接收数据

基于Http的客户端可以用QHttp来编写。关于如何使用QHttp编写客户端请求和响应处理函数的例子很多,QHttp类也提供了多种请求方式,如get、post、head、request,下面是一个get方法发送请求的例子:

 

HttpGet.h 

 

 这个HttpGet可以按照url地址进行Http请求,完成请求后会发出finished()的Signal,当QHttp所指定的全部请求完成时,会发出done()的Signal,HTTPGet类中自定义的Slot就是用来接收QHttp的done() Signal以进行相关处理的,这可以在HttpGet的实现中看到:

 

HttpGet.cpp

 

    HttpGet类实现了Http请求,并通过响应消息的槽httpRequestFinished函数对接收到的数据流进行解析,实现网络通信。

注意事项:

(1)书上和网上很多的例子都是直接根据url.path()来请求服务端的一个文件,但是url.path()函数得到的字符串不包含"?"及"?"号之后的字符串,所以不能只用url.path(),而应该还要加上查询字符串QString requestPath = url.path() + queryString

譬如:

QString queryString("?a=china&b=dazhi");

QUrl url("http://localhost:8081/" + queryString); //创建URL地址

QHttp http;

http.setHost(url.host(), url.port());

(2)//注意:一定要将m_httpGetId 保存,因为在通讯过程中,处理requestFinished消息的槽会判断m_httpGetId与当前状态下requestId是否相等,只有在相等时,才能正确进行解析客户端接收到的数据流,否则可能数据不完整。

 

二、服务端的响应与发送数据

    使用QTcpServer进行了服务器的创建,这里就不多说了,例子很多,但是QT的文档里和网上几乎没有关于如何使用QTcpSocket将数据传输到客户端的例子,我在使用QTcpSocket进行数据发送时,采用了如下方法:

譬如使用的QTcpSocket对象是tcpServerConnection,在响应请求消息并进行处理后,将数据发送到客户端,可以使用:

    tcpServerConnection->write(ba),其中ba是要输出到客户端的字节流QByteArray对象。

    有趣并折磨我很久的事情发生了!使用IE浏览器请求该服务器时,能够正确获取并解析数据,但我使用QHttp编写的客户端程序却死活也不能正确解析出接收到的字节流数据,跟踪后发现得到的数据流长度小于服务端的数据流长度,但为什么IE浏览器能正常解析呢???

    后来终于发现QT的服务端的response默认情况下不包括response header信息,而使用QHttp编写的客户端接收数据时又会默认认为接收到的数据包含了response header,导致它在解析数据流时,会把前面一部分数据作为header信息,而后面的才为作为传输的数据,这样解析出来数据流长度就会减少了,从而不能正确解析数据。因此我们需要在服务端发送数据时输出header信息,再输出我们所要传输的数据。

   下面是将影像数据流传输到客户端的示例:

  

 

三、总结

    QT的例子程序不够丰富全面,深度也不够,甚至网络编程中服务端和客户端的消息模式都有区别,导致不知道内部机制的情况下,无法正确编写程序,真希望QT在快速发展的同时能为我们开发人员提供更加全面的示例程序。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值