成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解 QT 4中構建多線程服務器

移動開發
對于服務器來說,多線程的這個特性太有用了,因為多線程使得服務器可能同時響應多個客戶端的請求,所以現在服務器大多采用多線程。

首先說一下對多線程這個名詞的理解過程。以前聽說過很多次多線程這個詞,而且往往與服務器聯系起來,因此一直把多線程誤解為服務器特有的功能;直到這次課程設計,仔細學習了一下多線程的機制,才知道真正的意思。簡單的來說,就是同時有多個線程一起運行,而不同的線程可以執行不同的操作。舉個例子,一個圖像處理工具,可以用鼠標一邊移動圖像,一邊用快捷鍵縮放圖像,此時,移動圖像、縮放圖像就是不同的線程來處理的,如果不支持多線程而是單線程的,那么只能挨個操作了。

而對于服務器來說,多線程的這個特性太有用了,因為多線程使得服務器可能同時響應多個客戶端的請求,所以現在服務器大多采用多線程,所以才會造成我開始的誤解。

不管是多線程,還是服務器,QT中已經封裝好了特定的類,所以使用起來也很方便。下面建立一個支持多線程、TCP的服務器。

首先建立一個服務器。新建一個類(Server)繼承QT中的QTcpServer類即可。服務器的職責是監聽端口。當監聽到有客戶端試圖與服務器建立連接的時候,分配socket與客戶端連接,再進行數據通信。QTcpServer的listen()方法執行監聽過程,可以指定監聽的地址和端口。若給定了QHostAddress類型的監聽地址,則監聽該地址,否則,監聽所有地址;若給定了quint16類型的監聽端口,則監聽該端口,否則,隨機選定一個監聽端口。

  1. view plaincopy to clipboardprint?  
  2. Server * server = new Server;      
  3. if(!server->listen(host,port)){      
  4. ...//error      
  5. }    

Server * server = new Server;if(!server->listen(host,port)){...//error}QTcpServer有一個虛函數incomingConnection(int socketDescriptor),服務器每當監聽到一個客戶端試圖建立連接的時候,會自動調用這個函數,因此,處理這個請求的過程就可以在這個函數中電影,即在子類Server的定義階段,重新定義incomingConnection()這個函數。

對于一個多線程的服務器,每當客戶端試圖連接的時候,服務器應該啟動一個線程,負責對這個客戶端進行服務,所以,incomingConnection()這個函數所要做的就是建立一個線程,而所建立的線程的作用就是對客戶端進行服務,而這其中建立socket連接是基礎。服務器在監聽到客戶端試圖建立socket連接時,會為此socket分配一個唯一的標識socketDescriptor,這個標識將在服務器端建立socket連接時使用,所以應提供給每一個線程。

在QT中使用多線程,建立一個類(Thread)繼承QThread類即可。QThread類也有一個虛函數,這個函數是run(),線程建立并啟動(QThread::start())后,就會執行這里面的代碼,因此,線程的邏輯過程就應該在run()里面定義。服務器的線程要根據socketDescriptor標識的socket建立連接,然后進行數據通信,所以要將socketDescriptor傳入到Thread中,前面說過,線程是在incomingConnection()里面建立,用構造函數將socketDescriptor傳入Thread類,再用socketDescriptor建立socket連接。

定義incomingConnection()

  1. view plaincopy to clipboardprint?  
  2. void incomingConnection(int socketDescriptor){      
  3.      Thread * thread = new Thread(socketDescriptor);      
  4.     thread->start();      
  5. }     
  6. void incomingConnection(int socketDescriptor){    Thread * thread = new Thread(socketDescriptor);    thread->start();}定義run()  
  7. view plaincopy to clipboardprint?  
  8. void run(){      
  9.      QTcpSocket * socket = new QTcpSocket(socketDescriptor);      
  10.      ...//數據通信      
  11. }     
  12. void run(){    QTcpSocket * socket = new QTcpSocket(socketDescriptor);    ...//數據通信}自此,一個簡單的多線程服務器建立完畢。 

寫的不好,望請指教。

QT4中socket通信

最近的軟件工程課程設計讓我重新開始使用QT,上次數據結構的課程設計也是用QT,雖然是做出來了,但是現在想想,那個時候對QT的理解,或者說得更廣一點,對OO的理解,簡直太差勁了,當然,人的知識是進步的,所以現在有這樣的感受是很正常的。雖然整體的開發工作還沒有完全結束,但是已經有了很多心得體會,所以特來記錄分享一下。

我們的系統采用的是C/S結構,所以客戶端與服務器通信是最關鍵,不幸的是,雖然我們沒有用過QT的socket類,我們也沒有估計好通信的難度,等到意識到第一次使用的困難時,已經是第5天了,始終沒有進展,我臨危受命?,F在是第6天,剛剛把通信模塊封裝好,算是對這兩天的突擊的一個回報。

#p#

我們遇到的問題socket已經建立,并且發送端已經將消息發送,但是接收端始終收不到消息。(我用的socket類型是TCP,也就是QTcpSocket類)

發送端(發送端一直不存在問題)代碼如下:

  1. view plaincopy to clipboardprint?  
  2. ... // 建立連接,客戶端和服務器端有區別,在此省略<BR>      
  3. QByteArray block;      
  4. QDataStream out(&block,QIODevice::WriteOnly);  // 寫信息至block中,用到QDataStream類<BR>      
  5. socket.write(block);// 信息寫完畢,寫入socket,由socket發送<BR>      
  6. socket.disconnectFormHost();      
  7. socket.waitForDisconnected();     
  8. ... // 建立連接,客戶端和服務器端有區別,在此省略QByteArray block;QDataStream out(&block,QIODevice::WriteOnly);  
  9. // 寫信息至block中,用到QDataStream類socket.write(block);
  10. // 信息寫完畢,寫入socket,由socket發送socket.disconnectFormHost();socket.waitForDisconnected();有問題的接收端代碼如下:  
  11. view plaincopy to clipboardprint?  
  12. ... // 建立連接<BR>      
  13. QDataStream in(&socket);// 接收socket中的數據流<BR>      
  14. ... // 從數據流 in 中讀數據     
  15. ... // 建立連接QDataStream in(&socket);// 接收socket中的數據流... // 從數據流 in 中讀數據 

以上是最原始的接收和發送端工作過程,調試過程中,分別講兩端的socket的狀態打印出來,結果是發送端為A connection is established. 而接收端為The socket has started establishing a connection. 也就是說發送端正確的建立了連接,并將數據寫入,而接收端只是正在建立連接,而并沒有建立好,所以是根本不會受到數據的。所以先要確保接收端的連接建立好。waitForConnected()方法就可以解決這個問題,它將一直等待直到連接已經建立。

改進后的接收端代碼:

  1. view plaincopy to clipboardprint?  
  2. ... // 建立連接<BR>      
  3. socket.waitForConnected(5000) // 5000表示等待的時間,默認參數為3000,單位是百萬分之一秒      
  4. QDataStream in(&socket);// 接收socket中的數據流<BR>      
  5. ... // 從數據流 in 中讀數據     
  6. ... // 建立連接socket.waitForConnected(5000)   
  7. // 5000表示等待的時間,默認參數為3000,單位是百萬分之一秒QDataStream in(&socket);  
  8. // 接收socket中的數據流...   
  9. // 從數據流 in 中讀數據此時,接收端輸出的socket狀態為A connection is established,連接成功建立。 

但是還是收不到信息,參考了一下別人的程序,再比對一下參考手冊,原來QTcpSocket的爺爺類(其實是父類QAbstractSocket的父類)QIODevice有一個readyRead的信號(signal),當信息準備好并可以讀的時候,這個信號就將發出,也就是說,只有當這個信號發出的時候,才可以讀消息。所以要把讀消息的動作read作為一個槽(slot),并將其與readyRead信號連接。

  1. view plaincopy to clipboardprint?  
  2. connect(&socket,SIGNAL(readyRead()),this,SLOT(read()));     
  3. connect(&socket,SIGNAL(readyRead()),this,SLOT(read())); 

但是直接觸發socket信號,而不用圖形界面的動作來觸發一個動作并由這個動作來觸發socket信號一直也觸發不了read這個動作。但是我要封裝成一個接口類提供給上層使用,用圖形界面自然是不現實的,于是翻閱了手冊,發現了一個QAbstractSocket類的一個方法——waitForReadyRead(),這個方法將一直等待到數據可以讀時結束,此時就可以讀數據了。方法也很簡單:

  1. view plaincopy to clipboardprint?  
  2. ... // 建立連接<BR>      
  3. socket.waitForConnected(5000) // 5000表示等待的時間,默認參數為3000,單位是百萬分之一秒<BR>      
  4. if(!socket.waitForReadyRead(3000)){//3000為等待時間,沒有默認的等待時間,單位是百萬分之一秒      
  5. return ;      
  6. }<BR>      
  7. QDataStream in(&socket);// 接收socket中的數據流<BR>      
  8. ... // 從數據流 in 中讀數據     
  9. ... // 建立連接socket.waitForConnected(5000) // 5000表示等待的時間,默認參數為3000,單位是百萬分之一秒
  10. if(!socket.waitForReadyRead(3000)){//3000為等待時間,沒有默認的等待時間,單位是百萬分之一秒return ;  
  11. }  
  12. QDataStream in(&socket);// 接收socket中的數據流... // 從數據流 in 中讀數據這樣,數據成功讀取出來,實現數據的通信。 

單向的數據傳輸問題解決了,然后再利用單向的數據通信組裝成雙向的數據通信,這過程中也會遇到不少問題,將在另一篇日志介紹。

原文地址:http://blog.csdn.net/dongfangyu/archive/2010/10/03/5919789.aspx

小結:關于詳解 QT 4中構建多線程服務器的內容介紹完了,希望本文對你有所幫助!更多內容請參考編輯推薦。

責任編輯:zhaolei 來源: 互聯網
相關推薦

2011-07-01 10:35:20

QT 多線程 TCP

2009-02-27 11:15:00

多線程服務器MTS專用服務器

2018-01-11 08:24:45

服務器模型詳解

2011-06-13 10:03:19

Qt 多線程 編程

2011-12-08 13:04:06

JavaNIO

2018-11-28 09:53:50

游戲服務器線程

2011-06-30 17:31:32

Qt 多線程 信號

2010-03-17 17:54:25

java Socket

2010-03-19 14:01:55

Java Socket

2009-02-18 10:41:16

多線程服務器穩定Java

2018-12-20 09:36:24

2011-06-20 13:43:08

Qt Socket 線程

2010-03-16 10:50:21

Java多線程服務器

2011-03-29 15:30:20

Zabbix服務器

2011-06-24 11:12:39

Qt 多線程 線程

2011-06-24 11:03:31

Qt 多線程 線程

2010-03-16 13:47:48

Java多線程服務器

2010-08-05 13:40:06

NFS服務器

2011-02-25 16:14:09

proftpdftp

2011-02-25 16:14:09

proftpdftp
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天搞天天操 | 在线观看免费毛片 | 99精品网站 | 九九综合 | 人妖一区 | 成人av网站在线观看 | 久久亚洲天堂 | 99久久精品免费看国产四区 | 亚洲精品美女视频 | 亚洲vs天堂| 亚洲欧美国产毛片在线 | 中文字幕一区二区三区不卡在线 | h在线免费观看 | 国产欧美视频一区 | 精品久久久久久久久久久下田 | 美女露尿口视频 | 国产精品国产a级 | 国产精品久久久久久久久久久免费看 | 毛片久久久 | 天天综合91 | 羞羞视频免费观看 | 日韩在线免费视频 | 中文字幕视频三区 | 欧美日韩国产一区二区三区 | 亚洲成av人片在线观看 | 国产一级片av | 极情综合网 | 久在线| av片毛片| 在线一区二区观看 | 亚洲精品一区二区三区在线观看 | 国产精品亚洲成在人线 | 欧美激情国产日韩精品一区18 | 亚洲成人一区二区三区 | 免费在线观看成人av | 久久6视频| 国产精品久久777777 | 超碰在线97国产 | 成人午夜免费视频 | 欧美v日韩v | 成人免费片 |