QT4中構建多執行緒的伺服器

2021-07-06 04:15:24 字數 4576 閱讀 4868

出錯和經驗

2009-04-28 15:43:48

閱讀12

字型大小:大

訂閱qt4中構建多執行緒的伺服器

首先說一下對多執行緒

這個名詞的理解過程。以前聽說過很多次多執行緒這個詞,而且往往與

伺服器聯絡起來,因此一直把多執行緒誤解為伺服器特有的功能;直到這次

課程設計

,仔細 學習

了一下多執行緒的機制,才知道真正的意思。簡單的來說,就是同時有多個執行緒一起執行,而不同的執行緒可以執行不同的操作。舉個例子,乙個影象處理工具,可以用滑鼠一邊移**像,一邊用快捷鍵縮放影象,此時,移**像、縮放影象就是不同的執行緒來處理的,如果不支援多執行緒而是單執行緒的,那麼只能挨個操作了。

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

不管是多執行緒,還是伺服器,qt中已經封裝好了特定的類,所以使用起來也很方便。

下面建立

乙個支援多執行緒、tcp的伺服器。

首先建立乙個伺服器。新建乙個類(server)繼承qt中的qtcpserver類即可。伺服器的職責是監聽埠。當監聽到有客戶端試圖與伺服器建立連線的時候,分配socket

與客戶端連線,再進行資料通訊

。qtcpserver的listen()方法執行監聽過程,可以指定監聽的位址和埠。若給定了qhostaddress型別的監聽位址,則監聽該位址,否則,監聽所有位址;若給定了quint16型別的監聽埠,則監聽該埠,否則,隨機選定乙個監聽埠。

view plain

copy to clipboard

print

?server * server =newserver;   

if(!server->listen(host,port))  

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()

view plain

copy to clipboard

print

?voidincomingconnection(intsocketdescriptor)  

定義run()

view plain

copy to clipboard

print

?voidrun()  

自此,乙個簡單的多執行緒伺服器建立完畢。

寫的不好,望請指教。

*************************===

qt4中socket通訊最

近的軟體工程

課程設計讓我重新開始使用qt,上次資料結構的課程設計

也是用qt,雖然是做出來了,但是現在想想,那個時候對qt的理解,或者說得更廣一點,對oo的理解,簡直太差勁了,當然,人的知識是進步的,所以現在有這樣的感受是很正常的。雖然整體的開發工作還沒有完全結束,但是已經有了很多心得體會,所以特來記錄分享一下。

我們的系統採用的是c/s結構,所以客戶端與伺服器

通訊是最關鍵,不幸的是,雖然我們沒有用過qt的socket

類,我們也沒有估計好通訊

的難度,等到意識到第一次使用的困難時,已經是第5天了,始終沒有進展,我臨危受命。現在是第6天,剛剛把通訊模組封裝好,算是對這兩天的突擊

的乙個回報。

我們遇到的問題socket已經建立

,並且傳送端已經將訊息傳送,但是接收端始終收不到訊息。(我用的socket型別是tcp,也就是qtcpsocket類)

傳送端(傳送端一直不存在問題)**如下:

view plain

copy to clipboard

print

?... // 建立連線,客戶端和伺服器端有區別,在此省略

qbytearray block;   

qdatastream out(&block,qiodevice::writeonly);  // 寫資訊至block中,用到qdatastream類

socket.write(block);// 資訊寫完畢,寫入socket,由socket傳送

socket.disconnectformhost();   

socket.waitfordisconnected();  

有問題的接收端**如下:

view plain

copy to clipboard

print

?... // 建立連線

qdatastream in(&socket);// 接收socket中的資料流

... // 從資料流 in 中讀資料

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

改進後的接收端**:

view plain

copy to clipboard

print

?... // 建立連線

socket.waitforconnected(5000) // 5000表示等待的時間,預設引數為3000,單位是百萬分之一秒 

qdatastream in(&socket);// 接收socket中的資料流

... // 從資料流 in 中讀資料

此時,接收端輸出的socket狀態為a connection is established,連線成功建立。

但是還是收不到資訊,參考了一下別人的程式,再比對一下參考手冊,原來qtcpsocket的爺爺類(其實是父類qabstractsocket的父類)qiodevice有乙個readyread的訊號(signal),當資訊準備好並可以讀的時候,這個訊號就將發出,也就是說,只有當這個訊號發出的時候,才可以讀訊息。所以要把讀訊息的動作read作為乙個槽(slot),並將其與readyread訊號連線。

view plain

copy to clipboard

print

?connect(&socket,signal(readyread()),this,slot(read()));  

但是直接觸發socket訊號,而不用圖形介面的動作來觸發乙個動作並由這個動作來觸發socket訊號一直也觸發不了read這個動作。但是我要封裝成乙個介面類提供給上層使用,用圖形介面自然是不現實的,於是翻閱了手冊,發現了乙個qabstractsocket類的乙個方法——waitforreadyread(),這個方法將一直等待到資料可以讀時結束,此時就可以讀資料了。方法也很簡單:

view plain

copy to clipboard

print

?... // 建立連線

socket.waitforconnected(5000) // 5000表示等待的時間,預設引數為3000,單位是百萬分之一秒

if(!socket.waitforreadyread(3000))

qdatastream in(&socket);// 接收socket中的資料流

... // 從資料流 in 中讀資料

這樣,資料成功讀取出來,實現資料的通訊。

單向的資料傳輸問題解決了,然後再利用單向的資料通訊組裝成雙向的資料通訊,這過程中也會遇到不少問題,將在另一篇日誌介紹。

QT4中構建多執行緒的伺服器

而對於伺服器來說,多執行緒的這個特性太有用了,因為多執行緒使得伺服器可能同時響應多個客戶端的請求,所以現在伺服器大多採用多執行緒,所以才會造成我開始的誤解。不管是多執行緒,還是伺服器,qt中已經封裝好了特定的類,所以使用起來也很方便。下面建立乙個支援多執行緒 tcp的伺服器。首先建立乙個伺服器。新建...

詳解 QT 4中構建多執行緒伺服器

首先說一下對多執行緒這個名詞的理解過程。以前聽說過很多次多執行緒這個詞,而且往往與伺服器聯絡起來,因此一直把多執行緒誤解為伺服器特有的功能 直到這次課程設計,仔細學習了一下多執行緒的機制,才知道真正的意思。簡單的來說,就是同時有多個執行緒一起執行,而不同的執行緒可以執行不同的操作。舉個例子,乙個影象...

構建多執行緒的伺服器

簡單的來說,就是同時有多個執行緒一起執行,而不同的執行緒可以執行不同的操作。舉個例子,乙個影象處理工具,可以用滑鼠一邊移 像,一邊用快捷鍵縮放影象,此時,移 像 縮放影象就是不同的執行緒來處理的,如果不支援多執行緒而是單執行緒的,那麼只能挨個操作了。而對於伺服器來說,多執行緒的這個特性太有用了,因為...