<wbr style="line-height:25px">Qt 4.6自带的threaddedfortuneserver是个简单明了的 Qt C/S网络编程server端程序的例子, 该例子演示了 QTcpServer与QThread配合的方法。 代码不多, 但包含了Qt网络编程的几个关键点。</wbr>
- FortuneServer类从QTcpServer派生, 调用QTcpServer::listen() 监听端口等待client连接
- FortuneServer重写了虚函数 incomingConnection()去接受client连接,并创建线程处理该连接
- FortuneThread是处理client连接的子线程, 在该线程里向client端写入数据结构非常简单。 笔者本来想照着这个架构写个接收client数据的小server,在写的过程中发现了一个很有意思的问题, 且听我慢慢道来。
不知道大家有没有发现, 其实FortuneServer这个类看起来是QTcpServer类的简单包装,并没有加入新的东西, 笔者就尝试去掉此子类直接使用QTcpServer。设想的程序架构是这样的:
- 使用QTcpServer监听端口等待client连接
- 在收到QTcpServer::newConnection信号时调用nextPendingConnection获得socket 连接, 将socket 连接的fd传送给子线程
- FortuneThread是处理client连接的子线程,得到连接的fd后创建一个QTcpSocket并用QTcpSocket::setSocketDescriptor,这样就可以用QTcpSocket的方法来监控fd的动向了。这里我们用QTcpSocket::waitForReadyRead等待client端发来的数据为了得到与client的连接的socket fd, 调用了QTcpServer::nextPendingConnection()方法获得一个QTcpSocket指针从该指针得到连接的fd,
再将该fd传送给子线程去处理。 看上去与原来的程序没什么区别, 但运行起来却发生了奇怪的问题,那就是有时server的waitForReadyRead返回true时却读不到数据(bytesAvailable() = 0)似乎client发来的数据丢了一样。 真是让人百思不得其解。
问题出了nextPendingConnection上。仔细回想一下我们的程序的架构,在server进程里调用nextPendingConnection获得一个QTcpSocket的指针,将此指针内的fd信息发送给子进程由子进程负责与client通讯。大家再想想QTcpSocket提供了那么多的API包括signal等, 这意味着什么?肯定Qt在底层对fd进行了监控啊,也就是说在我们的程序里出现了两个QTcpSocket分别在两个线程里对同一个fd进行了监控和操作,所以出现一些奇怪的现象也就不算奇怪了。
如果大家尝试对主线程的QTcpSocket进行处理就会发现,所谓“丢失”的数据都可以在这个socket里得到, 即有一部分socket的数据由于线程切换的关系由主线程的socket截获了。为了解决这个问题当然最好的办法还是沿用例子中的架构, 对QTcpServer进行派生,因为在incomingConnection的参数里可以直接得到fd,此时还没有创建QTcpSocket对此fd做任何操作, 是个干净的状态, 不会有任何冲突;另外还有一个办法是在不改变现有程序架构的情况下把这两个QTcpSocket搬到同一个线程里。这样也不会出现两个线程同时访问一个fd的情况。
具体是使用 QObject::moveToThread方法。 需要注意的是文档中对moveToThread有个说明, 有parent的object是不能被移动到其他线程中的,所以还需要把QTcpSocket给setParent(NULL)一下再moveToThread.
经过实验, 第二种方法也可以很好的工作。
分享到:
相关推荐
Qt5 Tutorial QTcpServer Loopback Example - 2018
QT QTcpServer实现多客户端连接。博客地址:https://blog.csdn.net/sinat_33859977/article/details/100110460
1.利用Tcp的稳定和高安全性传输文件 2.QTcpServer作为服务端监听所有客户端连接并作出响应 3.实时显示上传进度
https://blog.csdn.net/a1ngel/article/details/123150787?spm=1001.2014.3001.5501 博客地址
用Qt5.8实现的简单的C/S架构,实现服务器与客户端的网络通信,用到的核心类有:QTcpServer,QTcpSocket
封装基础的QTcpSocket、QThread、QTcpServer; 服务器监听后,每新来一个连接起一个线程,完全线程独立; 通过socketDescrptor传递socket; 不建议工程中使用该种模式,这只是一个简单的demo学习了解即可; 实际工程...
qt4.8的开发环境,qtcpserver,qtcpsocket开发的服务器端。
Qt涵盖大部分服务器工程集,包括Http协议,使用了第三方库;Qt类QLocalServer;Qt类QTcpServer;Qt类QWebSocketServer。
利用Qt的QTcpServer以及QTcpSocket类编写的局域网通信服务器
基于Qt开发的TCP通讯工具,包含客户端和服务端的工程文件夹,运用QTcpsocket和QTcpserver控件,实现文本发送,文件发送,代码简洁易懂,适合新手学习。
Qt-SslServer:使用QTcpServer和QSslSocket的SSL支持的Tcp Server类。 需要Qt和-std = c ++ 11进行编译。 目标机器上还必须有OpenSSL实现
本资源是基于QT的QTcpSocket和QTcpServer实现简单TCP业务demo,包含客户端和服务端工程源码,可以直接运行测试,也可直接用于项目开发。
初步实现QT客户端和服务器端传输文字和图片,并解决客户端关闭导致服务器端崩溃和异常关闭`,
Qt案例之利用QTcpSocket类和QTcpServer类设计简单TCP网络聊天应用,内容可能有少量bug,欢迎评论指出
用Qt的QTcpServer和QTcpSocket类的做一个Socket通讯的小程序。
最近接了一个单子,QT写的多线程Socket服务器+多客户端,虽然用qt做socket服务器不太合适,但是毕竟客户要求就做了,本以为很简单,后来才发现QT的QTcpServer真的不太好用,参考了好多网上的教程才弄明白,顺便记录...
qt例程,可以方便的了解qt程序代码的规则 对于初学者 有很大帮助
对于QT中QTcpServer和QTcpSocket的应用,最简单化的逻辑代码设计,附带打包程序,总代码少的批爆,适合初学和参考手册用。
这是用Qt编写的TCP通讯程序测试程序,在借鉴他人的基础上添加了一些自己的东西,比如支持多客户连接与通信。因为还没学QT的多线程,所以以下程序都是通过信号与槽实现的,而且对于我这个项目来说也够用了。 本程序在...
这个小demo是基于QT5编写的,采用TCP SOCKET通信方式,分为client和server端,有简单的界面,可进行信息发送与接收。