QT 线程池 + TCP 小试(二)实现通信功能

*免分资源链接点击打开链接http://download.csdn.net/detail/goldenhawking/4492378

        有了线程池,我们下一步就利用 QTcpServer 搭建一个服务器,接受客户端的连接,并把数据发送到线程池上。由于 QTcpServer 资料太多了,这里不在赘述。唯一值得注意的是,当客户端退出时,如果线程池队列中还有该客户的信息,这个信息还会被处理,只是无法再发送回去而已。其实,还可实现成客户端退出,就发一个信号到线程池,删除自己的所有任务。这个也很简单,但之所以没有做,因为这些数据的处理结果可能还会被其他消费者(而非生产者自己)使用,最典型的例子是从工业传感器上采集的数据,其生成的图像需要存储到设备中去。

       QTcpSocket的 Write 方法默认是支持大体积数据的,即使一次发了500MB的数据,只要硬件资源可以承受,调用也会成功并立刻返回。接受者会以一定的载荷大小不停的触发readyRead,直到发送全部成功。但是,为了能够观察到并控制收发队列中的数据包的大小、体积,我们在外层实现了一个发送队列,每次以 payLoad为大小发送数据包。这是从MFC中带来的习惯,很难说好坏。

 qghtcpserver.h

[cpp]   view plain  copy
  1. #ifndef QGHTCPSERVER_H  
  2. #define QGHTCPSERVER_H  
  3.   
  4. #include <QTcpServer>  
  5. #include <QMap>  
  6. #include <QList>  
  7.   
  8. class QGHTcpServer : public QTcpServer  
  9. {  
  10.     Q_OBJECT  
  11.   
  12. public:  
  13.     QGHTcpServer(QObject *parent,int nPayLoad = 4096);  
  14.     ~QGHTcpServer();  
  15.     //踢出所有客户  
  16.     void KickAllClients();  
  17.     QList <QObject *> clientsList();  
  18.     void SetPayload(int nPayload);  
  19. private:  
  20.     QMap<QObject *,QList<QByteArray> > m_buffer_sending;  
  21.     QMap<QObject *,QList<qint64> > m_buffer_sending_offset;  
  22.     QMap<QObject*,int> m_clientList;  
  23.     int m_nPayLoad;  
  24. public slots:  
  25.     //新的客户连接到来  
  26.     void new_client_recieved();  
  27.     //客户连接被关闭  
  28.     void client_closed();  
  29.     //新的数据到来  
  30.     void new_data_recieved();  
  31.     //一批数据发送完毕  
  32.     void some_data_sended(qint64);  
  33.     //客户端错误  
  34.     void displayError(QAbstractSocket::SocketError socketError);  
  35.     //向客户端发送数据  
  36.     void SendDataToClient(QObject * objClient,const QByteArray &  dtarray);  
  37.     //向客户端广播数据,不包括 objFromClient  
  38.     void BroadcastData(QObject * objFromClient,const QByteArray &  dtarray);  
  39. signals:  
  40.     //错误信息  
  41.     void evt_SocketError(QObject * senderSock ,QAbstractSocket::SocketError socketError);  
  42.     //新的客户端连接  
  43.     void evt_NewClientConnected(QObject * client);  
  44.     //客户端退出  
  45.     void evt_ClientDisconnected(QObject * client);  
  46.     //收到一批数据  
  47.     void evt_Data_recieved(QObject * ,const QByteArray &  );  
  48.     //一批数据被发送  
  49.     void evt_Data_transferred(QObject * client,qint64);  
  50. };  
  51.   
  52. #endif // QGHTCPSERVER_H  

qghtcpserver.cpp
[cpp]   view plain  copy
  1. #include "qghtcpserver.h"  
  2. #include <assert.h>  
  3. #include <QTcpSocket>  
  4. QGHTcpServer::QGHTcpServer(QObject *parent,int nPayLoad )  
  5.     : QTcpServer(parent),  
  6.     m_nPayLoad(nPayLoad)  
  7. {  
  8.     assert(m_nPayLoad>=256 && m_nPayLoad<=16*1024*1024);  
  9.     connect(this, SIGNAL(newConnection()), this, SLOT(new_client_recieved()));  
  10. }  
  11.   
  12. QGHTcpServer::~QGHTcpServer()  
  13. {  
  14.   
  15. }  
  16. QList <QObject *> QGHTcpServer::clientsList()  
  17. {  
  18.     return m_clientList.keys();  
  19. }  
  20. void QGHTcpServer::SetPayload(int nPayload)  
  21. {  
  22.     m_nPayLoad = nPayload;  
  23.     assert(m_nPayLoad>=256 && m_nPayLoad<=16*1024*1024);  
  24. }  
  25.   
  26. void QGHTcpServer::new_client_recieved()  
  27. {  
  28.     QTcpSocket * sock_client = nextPendingConnection();  
  29.     while (sock_client)  
  30.     {  
  31.         connect(sock_client, SIGNAL(readyRead()),this, SLOT(new_data_recieved()));  
  32.         connect(sock_client, SIGNAL(disconnected()),this,SLOT(client_closed()));  
  33.         connect(sock_client, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(displayError(QAbstractSocket::SocketError)));  
  34.         connect(sock_client, SIGNAL(bytesWritten(qint64)), this, SLOT(some_data_sended(qint64)));  
  35.         m_clientList[sock_client] = 0;  
  36.         emit evt_NewClientConnected(sock_client);  
  37.         sock_client = nextPendingConnection();  
  38.     }  
  39. }  
  40. void QGHTcpServer::client_closed()  
  41. {  
  42.     QTcpSocket * pSock = qobject_cast<QTcpSocket*>(sender());  
  43.     if (pSock)  
  44.     {  
  45.         emit evt_ClientDisconnected(pSock);  
  46.         m_buffer_sending.remove(pSock);  
  47.         m_buffer_sending_offset.remove(pSock);  
  48.         m_clientList.remove(pSock);  
  49.         pSock->deleteLater();  
  50.     }  
  51. }  
  52. void QGHTcpServer::new_data_recieved()  
  53. {  
  54.     QTcpSocket * pSock = qobject_cast<QTcpSocket*>(sender());  
  55.     if (pSock)  
  56.         emit evt_Data_recieved(pSock,pSock->readAll());  
  57. }  
  58. void QGHTcpServer::some_data_sended(qint64 wsended)  
  59. {  
  60.     QTcpSocket * pSock = qobject_cast<QTcpSocket*>(sender());  
  61.     if (pSock)  
  62.     {  
  63.         emit evt_Data_transferred(pSock,wsended);  
  64.         QList<QByteArray> & list_sock_data = m_buffer_sending[pSock];  
  65.         QList<qint64> & list_offset = m_buffer_sending_offset[pSock];  
  66.         while (list_sock_data.empty()==false)  
  67.         {  
  68.             QByteArray & arraySending = *list_sock_data.begin();  
  69.             qint64 & currentOffset = *list_offset.begin();  
  70.             qint64 nTotalBytes = arraySending.size();  
  71.             assert(nTotalBytes>=currentOffset);  
  72.             qint64 nBytesWritten = pSock->write(arraySending.constData()+currentOffset,qMin((int)(nTotalBytes-currentOffset),m_nPayLoad));  
  73.             currentOffset += nBytesWritten;  
  74.             if (currentOffset>=nTotalBytes)  
  75.             {  
  76.                 list_offset.pop_front();  
  77.                 list_sock_data.pop_front();  
  78.             }  
  79.             else  
  80.                 break;  
  81.         }  
  82.     }  
  83. }  
  84. void QGHTcpServer::displayError(QAbstractSocket::SocketError socketError)  
  85. {  
  86.     QTcpSocket * pSock = qobject_cast<QTcpSocket*>(sender());  
  87.     if (pSock)  
  88.     {  
  89.         emit evt_SocketError(pSock,socketError);  
  90.         pSock->disconnectFromHost();  
  91.     }  
  92. }  
  93.   
  94. void QGHTcpServer::SendDataToClient(QObject * objClient,const QByteArray &  dtarray)  
  95. {  
  96.     if (m_clientList.find(objClient)==m_clientList.end())  
  97.         return;  
  98.     QTcpSocket * pSock = qobject_cast<QTcpSocket*>(objClient);  
  99.     if (pSock&&dtarray.size())  
  100.     {  
  101.         QList<QByteArray> & list_sock_data = m_buffer_sending[pSock];  
  102.         QList<qint64> & list_offset = m_buffer_sending_offset[pSock];  
  103.         if (list_sock_data.empty()==true)  
  104.         {  
  105.             qint64 bytesWritten = pSock->write(dtarray.constData(),qMin(dtarray.size(),m_nPayLoad));  
  106.             if (bytesWritten < dtarray.size())  
  107.             {  
  108.                 list_sock_data.push_back(dtarray);  
  109.                 list_offset.push_back(bytesWritten);  
  110.             }  
  111.         }  
  112.         else  
  113.         {  
  114.             list_sock_data.push_back(dtarray);  
  115.             list_offset.push_back(0);  
  116.         }             
  117.     }     
  118. }  
  119. void QGHTcpServer::BroadcastData(QObject * objClient,const QByteArray &  dtarray)  
  120. {  
  121.     for(QMap<QObject *,int>::iterator p = m_clientList.begin();p!=m_clientList.end();p++)  
  122.     {  
  123.         QTcpSocket * pSock = qobject_cast<QTcpSocket*>(p.key());  
  124.         if (pSock&&dtarray.size()&&pSock!=objClient)  
  125.         {  
  126.             QList<QByteArray> & list_sock_data = m_buffer_sending[pSock];  
  127.             QList<qint64> & list_offset = m_buffer_sending_offset[pSock];  
  128.             if (list_sock_data.empty()==true)  
  129.             {  
  130.                 qint64 bytesWritten = pSock->write(dtarray.constData(),qMin(dtarray.size(),m_nPayLoad));  
  131.                 if (bytesWritten < dtarray.size())  
  132.                 {  
  133.                     list_sock_data.push_back(dtarray);  
  134.                     list_offset.push_back(bytesWritten);  
  135.                 }  
  136.                 else  
  137.                 {  
  138.                     list_sock_data.push_back(dtarray);  
  139.                     list_offset.push_back(0);  
  140.                 }             
  141.             }  
  142.         }     
  143.     }  
  144. }  
  145. void QGHTcpServer::KickAllClients()  
  146. {  
  147.     QList<QObject *> clientList = m_clientList.keys();  
  148.     foreach(QObject * obj,clientList)  
  149.     {  
  150.         QTcpSocket * pSock = qobject_cast<QTcpSocket*>(obj);  
  151.         if (pSock)  
  152.         {  
  153.             pSock->disconnectFromHost();  
  154.         }     
  155.     }  
  156.   
  157. }  
下一次,我会介绍最后的实现功能。



FROM:http://blog.csdn.net/goldenhawking/article/details/7854621

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值