Qt 多线程服务器2

来源:互联网 发布:数据颗粒度是什么意思 编辑:程序博客网 时间:2024/04/29 04:16
  1. //服务器端   
  2. //dialog.h   
  3. #ifndef DIALOG_H   
  4. #define DIALOG_H   
  5.   
  6. #include <QtGui>   
  7. #include <QtNetwork>   
  8. #include "fortuneserver.h"   
  9.   
  10. class Dialog : public QDialog  
  11. {  
  12.     Q_OBJECT  
  13.   
  14. public:  
  15.     Dialog(QWidget *parent = 0);  
  16.   
  17. private:  
  18.     QLabel *statusLabel;  
  19.     QPushButton *quitButton;  
  20.     FortuneServer server;  
  21. };  
  22.   
  23. #endif   
  24.   
  25.   
  26.   
  27. //fortuneserver.h   
  28. #ifndef FORTUNESERVER_H   
  29. #define FORTUNESERVER_H   
  30.   
  31. #include <QStringList>   
  32. #include <QTcpServer>   
  33.   
  34. class FortuneServer : public QTcpServer  
  35. {  
  36.     Q_OBJECT  
  37. public:  
  38.     FortuneServer(QObject *parent = 0);  
  39. protected:  
  40.     void incomingConnection(int socketDescriptor);  
  41. private:  
  42.     QStringList fortunes;  
  43. };  
  44.   
  45. #endif   
  46.   
  47.   
  48.   
  49. //fortunethread.h   
  50. #ifndef FORTUNETHREAD_H   
  51. #define FORTUNETHREAD_H   
  52.   
  53. #include <QThread>   
  54. #include <QTcpSocket>   
  55.   
  56. class FortuneThread : public QThread  
  57. {  
  58.     Q_OBJECT  
  59. public:  
  60.     FortuneThread(int socketDescriptor, QObject *parent);  
  61.     void run();  
  62. private:  
  63.     int socketDescriptor;  
  64.     QString theString;  
  65.     QTcpSocket *tcpSocket;  
  66.     qint16 blockSize;  
  67.   
  68.     public slots:  
  69.         void readMessage();  
  70.         void sendMessage();  
  71. signals:  
  72.         void error(QTcpSocket::SocketError socketError);  
  73. };  
  74.   
  75. #endif   
  76.   
  77.   
  78.   
  79. //dialog.cpp   
  80. #include "dialog.h"   
  81.   
  82. Dialog::Dialog(QWidget *parent)  
  83.     : QDialog(parent)  
  84. {  
  85.     statusLabel = new QLabel;  
  86.     quitButton = new QPushButton(tr("Quit"));  
  87.     quitButton->setAutoDefault(false);  
  88.   
  89.     if (!server.listen(QHostAddress::Any, 8888))   
  90.     {  
  91.         QMessageBox::critical(this, tr("Threaded Fortune Server"),  
  92.                               tr("Unable to start the server: %1.")  
  93.                               .arg(server.errorString()));  
  94.         close();  
  95.         return;  
  96.     }  
  97.   
  98.     QString ipAddress;  
  99.     QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();  
  100.     for (int i = 0; i < ipAddressesList.size(); ++i) {  
  101.         if (ipAddressesList.at(i) != QHostAddress::LocalHost &&  
  102.             ipAddressesList.at(i).toIPv4Address()) {  
  103.             ipAddress = ipAddressesList.at(i).toString();  
  104.             break;  
  105.         }  
  106.     }  
  107.     if (ipAddress.isEmpty())  
  108.         ipAddress = QHostAddress(QHostAddress::LocalHost).toString();  
  109.     statusLabel->setText(tr("The server is running on\n\nIP: %1\nport: %2\n\n"  
  110.                             "Run the Fortune Client example now.")  
  111.                          .arg(ipAddress).arg(server.serverPort()));  
  112.   
  113.     connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));  
  114.   
  115.     QHBoxLayout *buttonLayout = new QHBoxLayout;  
  116.     buttonLayout->addStretch(1);  
  117.     buttonLayout->addWidget(quitButton);  
  118.     buttonLayout->addStretch(1);  
  119.   
  120.     QVBoxLayout *mainLayout = new QVBoxLayout;  
  121.     mainLayout->addWidget(statusLabel);  
  122.     mainLayout->addLayout(buttonLayout);  
  123.     setLayout(mainLayout);  
  124.   
  125.     setWindowTitle(tr("Threaded Fortune Server"));  
  126. }  
  127.   
  128.   
  129.   
  130. //fortuneserver.cpp   
  131. #include "fortuneserver.h"   
  132. #include "fortunethread.h"   
  133.   
  134. FortuneServer::FortuneServer(QObject *parent)  
  135.     : QTcpServer(parent)  
  136. {  
  137. }  
  138.   
  139. void FortuneServer::incomingConnection(int socketDescriptor)  
  140. {  
  141.     FortuneThread *thread = new FortuneThread(socketDescriptor, this);  
  142.     connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));  
  143.     thread->start();  
  144. }  
  145.   
  146.   
  147.   
  148. //fortunethread.cpp   
  149. #include "fortunethread.h"   
  150.   
  151. FortuneThread::FortuneThread(int socketDescriptor, QObject *parent)  
  152.     : QThread(parent), socketDescriptor(socketDescriptor)  
  153. {  
  154.     blockSize = 0;  
  155.       
  156. }  
  157.   
  158. void FortuneThread::run()  
  159. {  
  160.     tcpSocket = new QTcpSocket;  
  161.     if (!tcpSocket->setSocketDescriptor(socketDescriptor))  
  162.     {  
  163.         emit error(tcpSocket->error());  
  164.         return;  
  165.     }  
  166.     connect(tcpSocket, SIGNAL(readyRead()), this,   
  167.         SLOT(readMessage()), Qt::DirectConnection);  
  168.     exec();  
  169. }  
  170.   
  171. void FortuneThread::readMessage()  
  172. {  
  173.     QDataStream in(tcpSocket);  
  174.     in.setVersion(QDataStream::Qt_4_0);  
  175.     if (blockSize == 0)  
  176.     {  
  177.         if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))  
  178.             return;  
  179.         in >> blockSize;  
  180.     }  
  181.     if (tcpSocket->bytesAvailable() < blockSize)  
  182.         return;  
  183.   
  184.     in >> theString;  
  185.     blockSize = 0;  
  186.     sendMessage();  
  187. }  
  188.   
  189. void FortuneThread::sendMessage()  
  190. {  
  191.     QByteArray block;  
  192.     QDataStream out(&block, QIODevice::WriteOnly);  
  193.     out.setVersion(QDataStream::Qt_4_0);  
  194.   
  195.     out << (quint16)0;  
  196.     out << theString;  
  197.     out.device()->seek(0);  
  198.     out << (quint16)(block.size() - sizeof(quint16));  
  199.   
  200.     tcpSocket->write(block);  
  201. }  
  202.   
  203.   
  204. //main.cpp   
  205. #include <QApplication>   
  206. #include <QtCore>   
  207. #include "dialog.h"   
  208.   
  209. int main(int argc, char *argv[])  
  210. {  
  211.     QApplication app(argc, argv);  
  212.     Dialog dialog;  
  213.     dialog.show();  
  214.     return dialog.exec();  
  215. }  
  216.   
  217.   
  218.   
  219.   
  220.   
  221.   
  222. //客户端   
  223. //client.h   
  224. #ifndef TRYCLI_H_   
  225. #define TRYCLI_H_   
  226.   
  227. #include <QtNetwork>   
  228. #include <QtGui>   
  229. #include <QtCore>   
  230.   
  231. class Client : public QWidget  
  232. {  
  233.     Q_OBJECT  
  234. private:  
  235.     bool isConnected;  
  236.     QLineEdit *serverIpEdit;  
  237.     QLabel *label;  
  238.     QLineEdit *strEdit;  
  239.     QPushButton *startButton;  
  240.   
  241.     QTcpSocket *tcpClient;  
  242.     quint16 blockSize;  
  243.     QString sendString;  
  244.     QString readString;  
  245.   
  246. public:  
  247.     Client();  
  248.     ~Client();  
  249.   
  250.     public slots:  
  251.         void displayError(QAbstractSocket::SocketError socketError);  
  252.         void newConnect();  
  253.         void readMessage();  
  254.         void sendMessage();  
  255.   
  256. };  
  257.   
  258. #endif   
  259.   
  260.   
  261. //client.cpp   
  262. #include "client.h"   
  263. #include <QtGui/QMessageBox>   
  264. #include <QtGui/QHBoxLayout>   
  265. #include <QtEvents>   
  266.   
  267. Client::Client()  
  268. {  
  269.     setWindowTitle("Client");  
  270.     resize(300, 100);  
  271.   
  272.     serverIpEdit = new QLineEdit("127.0.0.1");  
  273.     startButton = new QPushButton("start");  
  274.     strEdit = new QLineEdit;  
  275.     label = new QLabel("Emtpy");  
  276.     isConnected = false;  
  277.   
  278.     QVBoxLayout *layout = new QVBoxLayout;  
  279.     layout->addWidget(serverIpEdit);  
  280.     layout->addWidget(label);  
  281.     layout->addWidget(strEdit);  
  282.     layout->addWidget(startButton);  
  283.     setLayout(layout);  
  284.   
  285.     tcpClient = new QTcpSocket(this);  
  286.     connect(startButton, SIGNAL(clicked()), this, SLOT(newConnect()));  
  287.     connect(tcpClient, SIGNAL(connected()), this, SLOT(sendMessage()));  
  288.     connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readMessage()));  
  289.     connect(tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),  
  290.         this, SLOT(displayError(QAbstractSocket::SocketError)));  
  291. }  
  292.   
  293. Client::~Client()  
  294. {  
  295.   
  296. }  
  297.   
  298. void Client::newConnect()  
  299. {  
  300.     blockSize = 0;  
  301.     if(!isConnected)  
  302.     {  
  303.         tcpClient->abort();  
  304.         tcpClient->connectToHost(serverIpEdit->text(), 8888);  
  305.         isConnected = true;  
  306.     }  
  307.     else  
  308.         sendMessage();  
  309. }  
  310.   
  311. void Client::sendMessage()  
  312. {  
  313.     QByteArray block;  
  314.     QDataStream out(&block, QIODevice::WriteOnly);  
  315.     out.setVersion(QDataStream::Qt_4_0);  
  316.   
  317.     sendString = strEdit->text();  
  318.     out << (quint16)0;  
  319.     out << sendString;  
  320.     out.device()->seek(0);  
  321.     out << (quint16)(block.size() - sizeof(quint16));  
  322.   
  323.     tcpClient->write(block);  
  324. }  
  325.   
  326. void Client::readMessage()  
  327. {  
  328.     QDataStream in(tcpClient);  
  329.     in.setVersion(QDataStream::Qt_4_0);  
  330.   
  331.     if (blockSize == 0)  
  332.     {  
  333.         if (tcpClient->bytesAvailable() < (int)sizeof(quint16))  
  334.             return;  
  335.         in >> blockSize;  
  336.     }  
  337.     if (tcpClient->bytesAvailable() < blockSize)  
  338.         return;  
  339.   
  340.     in >> readString;  
  341.     label->setText(readString);  
  342. }  
  343.   
  344. void Client::displayError(QAbstractSocket::SocketError socketError)  
  345. {  
  346.     switch (socketError) {  
  347.     case QAbstractSocket::RemoteHostClosedError:  
  348.         break;  
  349.     case QAbstractSocket::HostNotFoundError:  
  350.         QMessageBox::information(this, tr("Fortune Client"),  
  351.             tr("The host was not found. Please check the "  
  352.             "host name and port settings."));  
  353.         break;  
  354.     case QAbstractSocket::ConnectionRefusedError:  
  355.         QMessageBox::information(this, tr("Fortune Client"),  
  356.             tr("The connection was refused by the peer. "  
  357.             "Make sure the fortune server is running, "  
  358.             "and check that the host name and port "  
  359.             "settings are correct."));  
  360.         break;  
  361.     default:  
  362.         QMessageBox::information(this, tr("Fortune Client"),  
  363.             tr("The following error occurred: %1.")  
  364.             .arg(tcpClient->errorString()));  
  365.     }  
  366. }  
  367.   
  368.   
  369. //main.cpp   
  370. #include "client.h"   
  371. #include <QtGui/QApplication>   
  372.   
  373. int main(int argc, char *argv[])  
  374. {  
  375.     QApplication a(argc, argv);  
  376.     Client w;  
  377.     w.show();  
  378.     return a.exec();  
  379. }