盧 照 何志林
(運(yùn)城學(xué)院計(jì)算機(jī)科學(xué)與技術(shù)系 運(yùn)城 044000)
?
基于TCP的多線程通信在陰極保護(hù)軟件中的應(yīng)用*
盧照何志林
(運(yùn)城學(xué)院計(jì)算機(jī)科學(xué)與技術(shù)系運(yùn)城044000)
摘要通信服務(wù)軟件是陰極保護(hù)無線終端監(jiān)控系統(tǒng)的重要組成部分,通信的實(shí)時(shí)性和準(zhǔn)確性直接影響到整個(gè)陰保軟件的性能和決策。系統(tǒng)運(yùn)用.NET框架中的Socket類進(jìn)行開發(fā),Winsock32 API提供了套接字服務(wù),為實(shí)現(xiàn)網(wǎng)絡(luò)編程提供了大量的方法。軟件利用多線程技術(shù),采用了TCP協(xié)議的套接字通信,應(yīng)用于實(shí)際陰極保護(hù)軟件系統(tǒng)中,實(shí)現(xiàn)了終端設(shè)備與服務(wù)器之間的實(shí)時(shí)通信,為陰保軟件提供了實(shí)時(shí)的數(shù)據(jù)信息,起到了對(duì)終端設(shè)備狀態(tài)實(shí)時(shí)的監(jiān)測(cè)作用。系統(tǒng)在實(shí)際應(yīng)用中穩(wěn)定性和實(shí)時(shí)性都比較令人滿意。
關(guān)鍵詞網(wǎng)絡(luò)通信; 多線程; Socket; TCP
Class NumberTP393.1
陰極保護(hù)技術(shù)是電化學(xué)保護(hù)技術(shù)的一種,其原理是向被腐蝕金屬結(jié)構(gòu)物表面施加一個(gè)外加電流,被保護(hù)結(jié)構(gòu)物成為陰極,從而使得金屬腐蝕發(fā)生的電子遷移得到抑制,避免或減弱腐蝕的發(fā)生[1]。
陰極保護(hù)無線終端監(jiān)控系統(tǒng)就是通過計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)對(duì)設(shè)備的狀態(tài)數(shù)據(jù)進(jìn)行實(shí)時(shí)監(jiān)測(cè),主要有兩種類型,一種是生產(chǎn)現(xiàn)場(chǎng)沒有監(jiān)控系統(tǒng),而是將數(shù)據(jù)采集之后直接送至遠(yuǎn)程計(jì)算機(jī)進(jìn)行處理,這種遠(yuǎn)程測(cè)控和通常的現(xiàn)場(chǎng)測(cè)控沒有太大的區(qū)分,只是數(shù)據(jù)傳輸比現(xiàn)場(chǎng)測(cè)控系統(tǒng)距離要遙遠(yuǎn);另一種是現(xiàn)場(chǎng)監(jiān)控和遠(yuǎn)程監(jiān)控并存。本文主要研究如何采用多線程技術(shù)解決大量外圍設(shè)備數(shù)據(jù)通過計(jì)算機(jī)網(wǎng)絡(luò)發(fā)送給遠(yuǎn)程服務(wù)器。
套接字是通信的基石,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元[2]??梢詫⑻捉幼挚醋鞑煌鳈C(jī)間的進(jìn)程進(jìn)行雙向通信的端點(diǎn),它構(gòu)成了單個(gè)主機(jī)內(nèi)及整個(gè)網(wǎng)絡(luò)間的編程界面。套接字存在于通信域中,通信域是為了處理一般的線程通過套接字通信而引進(jìn)的一種抽象概念。套接字有兩種不同的類型:流套接字和數(shù)據(jù)報(bào)套接字[3]。要通過互聯(lián)網(wǎng)進(jìn)行通信,至少需要一對(duì)套接字,其中一個(gè)運(yùn)行于客戶機(jī)端,另一個(gè)運(yùn)行于服務(wù)器端。
TCP/IP是Internet上廣泛使用的一種數(shù)據(jù)通信協(xié)議,可用于不同機(jī)器之間的互聯(lián)。在網(wǎng)絡(luò)編程中,編程人員不需要掌握TCP/IP的具體實(shí)現(xiàn)細(xì)節(jié),只需利用協(xié)議的網(wǎng)絡(luò)編程接口套接字即可[4]。在Windows中,網(wǎng)絡(luò)編程接口是Windows Socket它包含了標(biāo)準(zhǔn)的Berkley Sockets的功能調(diào)用的集合。TCP/IP協(xié)議的應(yīng)用一般采用客戶/服務(wù)器模式,面向連接的應(yīng)用調(diào)用如圖1所示[5]。
圖1 服務(wù)端和客戶端套接字對(duì)應(yīng)調(diào)用關(guān)系
3.1通信基礎(chǔ)協(xié)議選擇
在網(wǎng)絡(luò)通信協(xié)議選擇上,采用Windows Socket實(shí)現(xiàn)了常用的Socket通信應(yīng)用類型有兩種[6]:一種是面向連接的傳輸控制協(xié)議(Transmission Control Protocol,TCP)服務(wù)應(yīng)用,第二種是用于無連接的用戶數(shù)據(jù)報(bào)協(xié)議(User Data Protocol,UDP)服務(wù)應(yīng)用。對(duì)于TCP通信來說,在發(fā)送和接收數(shù)據(jù)之前先要與對(duì)方建立連接,是一種可靠性較高的傳輸協(xié)議。采用UDP協(xié)議在發(fā)生和接收數(shù)據(jù)前不需要建立連接,可以將數(shù)據(jù)先發(fā)送到網(wǎng)絡(luò)上,再根據(jù)報(bào)文信息找到目標(biāo)機(jī)器,實(shí)時(shí)性要高于TCP傳輸,但準(zhǔn)確性不如TCP傳輸,可能會(huì)丟失數(shù)據(jù)包[7~8]。
從文章研究?jī)?nèi)容出發(fā),是為了將終端設(shè)備的狀態(tài)數(shù)據(jù)信息發(fā)送到服務(wù)器端,然后根據(jù)狀態(tài)數(shù)據(jù)決定設(shè)備的性能和工作如何。因此,對(duì)數(shù)據(jù)的實(shí)時(shí)性要求不高,但對(duì)數(shù)據(jù)的準(zhǔn)確性要求較高。因此,軟件采用了基于TCP協(xié)議進(jìn)行Socket通信。
3.2工作流程
在陰極保護(hù)無線終端監(jiān)控系統(tǒng)中,各個(gè)檢測(cè)的管道設(shè)備都分散在野外各個(gè)地點(diǎn),通過Internet網(wǎng)絡(luò)將數(shù)據(jù)發(fā)送到通信服務(wù)器上,服務(wù)器端接收數(shù)據(jù)并根據(jù)接收的信息進(jìn)行必要的應(yīng)答,然后將這些數(shù)據(jù)信息進(jìn)行備份后轉(zhuǎn)發(fā)給應(yīng)用服務(wù)器,應(yīng)用服務(wù)器將接收的數(shù)據(jù)進(jìn)行解析后存放到各個(gè)表中,提供給客戶的應(yīng)用軟件查詢使用。圖2為基本的數(shù)據(jù)發(fā)送結(jié)構(gòu)圖。
圖2 終端設(shè)備發(fā)送結(jié)構(gòu)圖
4.1通信線程的建立和初始化
當(dāng)啟動(dòng)服務(wù)器端以后,服務(wù)器端就一直處于監(jiān)聽狀態(tài),等待客戶端連接,當(dāng)有終端設(shè)備連接服務(wù)器時(shí),建立一個(gè)新的線程進(jìn)行數(shù)據(jù)傳輸。
Listener = New TcpListener(localAddr, Port)
Listener.Start()
Listener.BeginAcceptTcpClient(AddressOfHandleAsyncConnection, Listener)
……
‘建立連接對(duì)象
Dim sessionComm As SessionCommunications = New SessionCommunications(client, conID)
SessionCollection.Insert(0, sessionComm)
Dim new Session As New Thread(AddressOf Run)
newSession.IsBackground = True
newSession.Start(SessionCollection.Item(0))‘開始運(yùn)行新建線程Run代碼
圖3所示是整個(gè)通信程序的結(jié)構(gòu)流程,當(dāng)有多個(gè)設(shè)備同時(shí)連接時(shí),服務(wù)器端會(huì)建立連接各自的連接對(duì)象,并插入到列表中,同時(shí)分別開辟多個(gè)對(duì)應(yīng)的線程為每個(gè)連接對(duì)象服務(wù),從而保證數(shù)據(jù)通信之間的獨(dú)立性和完整性[9]。
圖3 整體程序流程圖
4.2通信線程的核心操作
在通信線程的共有操作Run函數(shù)中,首先給各個(gè)線程分配必要的通信緩存空間,然后根據(jù)參數(shù)獲取線程的標(biāo)識(shí),建立線程通信的客戶端資源信息,如通過連接對(duì)象獲取客戶端Socket流,通過流可以進(jìn)行Socket的讀寫操作[10]。
Server = ConnsessionObj.theClient
Stream = Server.GetStream()
當(dāng)設(shè)置好線程初始狀態(tài)后,服務(wù)器端的連接線程開始進(jìn)入循環(huán)工作狀態(tài),在循環(huán)工作狀態(tài)中通過Stream.DataAvailable()方法判斷流中是否有數(shù)據(jù)可讀,如果暫時(shí)無數(shù)據(jù)可讀,通過設(shè)置Havedata標(biāo)記為0,同時(shí)延時(shí)一定時(shí)間,可以讓出CPU給其他線程工作,若是有可讀數(shù)據(jù),Havedata設(shè)置為1,可以通過函數(shù)Stream.Read()方法獲取客戶端發(fā)送的數(shù)據(jù)。如此反復(fù)循環(huán)進(jìn)行判斷操作。服務(wù)器定期需要給客戶端發(fā)送01字符,判斷客戶是否還在線,如果客戶端已經(jīng)斷開連接,則服務(wù)器端需要的操作是從連接對(duì)象列表中刪除該連接對(duì)象,同時(shí)釋放連接資源,操作如下:
ForiAsInteger = 0 ToSessionCollection.Count-1
IfCType(SessionCollection(i), SessionCommunications).theClientIssession.theClientThen
SessionCollection.RemoveAt(i)
Exit For
EndIf
Next
session.Close()
session.theClient = Nothing
GC.GetTotalMemory(True)
圖4為線程操作的具體流程圖。
圖4 線程執(zhí)行流程圖
核心代碼如下:
IfHavedata = 0 Then
weHaveThePuck = True
IfStream.DataAvailable() Then
Havedata = 1
Else
’線程停留
Thread.Sleep(100)
EndIf
Else
DimreadlenAsInteger
Try
readlen = Stream.Read(strStream, 0, strStream.Length)
Catch ex AsException
session.Close()
session.theClient = Nothing
GC.Collect()
GC.GetTotalMemory(True)
’GC.WaitForPendingFinalizers()
Exit Do
EndTry
DimstrAsString = System.Text.Encoding.ASCII.GetString(strStream, 0, readlen).Trim()
packetSize = str.Length
theBuffer = System.Text.Encoding.ASCII.GetBytes(str.Substring(0, packetSize))
IpEndPoint = CType(Server.Client.RemoteEndPoint, Net.IPEndPoint) '獲取遠(yuǎn)程IP和端口號(hào)
RcvBytes(theBuffer, session.sessionID, 1)
SendServer(theBuffer)
Havedata = 0
Stream.Flush()
EndIf
idleTimer = Now
EndIf
If Now >idleTimer.AddMilliseconds(300) Then
Thread.Sleep(200)
EndIf
Loop
通信服務(wù)軟件接收數(shù)據(jù)運(yùn)行界面如圖5所示。
圖5 運(yùn)行界面
4.3通信數(shù)據(jù)處理機(jī)制
通信服務(wù)器接收到數(shù)據(jù)后,會(huì)根據(jù)通信協(xié)議,根據(jù)各個(gè)消息頭內(nèi)容,首先將數(shù)據(jù)信息存放到Oracle數(shù)據(jù)中,然后再對(duì)收到的數(shù)據(jù)進(jìn)行解析,分別存放到相應(yīng)的各個(gè)表中,供前臺(tái)頁面調(diào)用查詢。需要說明的是當(dāng)數(shù)據(jù)大量接收時(shí),在程序中進(jìn)行數(shù)據(jù)解析是不行的,造成CPU的使用率很高,這里通過在Oracle數(shù)據(jù)庫的觸發(fā)器中編寫代碼進(jìn)行數(shù)據(jù)解析,對(duì)通信服務(wù)器的分析數(shù)據(jù)壓力降低了很多。
在通信軟件系統(tǒng)開發(fā)和調(diào)試過程中,遇到的一些關(guān)鍵性問題,現(xiàn)將問題進(jìn)行歸納總結(jié)如下,為在同類軟件開發(fā)中提供參考價(jià)值。
1) 連接對(duì)象重復(fù)問題解決
在陰極保護(hù)無線終端監(jiān)控系統(tǒng)中,所有終端設(shè)備與服務(wù)器之間的連接是間歇性的,只有當(dāng)有數(shù)據(jù)時(shí)才連接服務(wù)器并發(fā)送數(shù)據(jù),發(fā)送數(shù)據(jù)的條數(shù)和發(fā)送時(shí)間的長(zhǎng)度也是不固定的。終端發(fā)送結(jié)束后會(huì)自動(dòng)斷開連接,在這種情況下,服務(wù)器端并不知道客戶端已經(jīng)斷開,在連接對(duì)象列表中還保存著該對(duì)象,當(dāng)該終端第二次連接時(shí)會(huì)生成一個(gè)新的連接對(duì)象存放在列表中,如此反復(fù),造成連接對(duì)象列表出現(xiàn)多個(gè)同一個(gè)設(shè)備的連接對(duì)象,通信服務(wù)軟件的內(nèi)存會(huì)不斷上升,占用很大內(nèi)存資源。針對(duì)以上問題,在服務(wù)器端監(jiān)聽到有終端設(shè)備請(qǐng)求連接時(shí),首先從連接對(duì)象列表中進(jìn)行遍歷,將之前未釋放的連接對(duì)象關(guān)閉釋放掉,然后生成新的連接對(duì)象,插入到列表中,從而保證了列表中每個(gè)終端設(shè)備連接對(duì)象的唯一性。
2) 客戶端連接斷開問題解決
在陰極保護(hù)無線終端監(jiān)控系統(tǒng)中,由于終端設(shè)備和服務(wù)器之間沒有設(shè)置數(shù)據(jù)發(fā)送完成的握手信號(hào),造成客戶端已經(jīng)斷開了連接,服務(wù)器端不清楚是否斷開,連接對(duì)象的資源得不到釋放,占據(jù)的內(nèi)存空間不斷上升。這里的解決方法有兩種:第一種是間隔固定的時(shí)間后,服務(wù)端斷開客戶端連接釋放資源。第二種方法是服務(wù)器在很短的時(shí)間間隔內(nèi)定期給客戶端發(fā)送數(shù)據(jù),如果客戶端已經(jīng)斷開,此時(shí)會(huì)發(fā)生異常,通過捕捉異常信息進(jìn)行判斷客戶端是否已經(jīng)斷開。兩種方法需要根據(jù)具體的實(shí)際情況來決定采用哪種方法較好。
3) 線程CPU資源消耗問題解決
多線程執(zhí)行函數(shù)中,采用了Do…Loop循環(huán)語句,線程中不斷在判斷終端是否有發(fā)送來的數(shù)據(jù),在對(duì)線程運(yùn)行環(huán)境下,CPU的消耗是很大的,因此,在循環(huán)中進(jìn)行判斷,如果沒有數(shù)據(jù)發(fā)送過來,該線程進(jìn)行適當(dāng)?shù)难訒r(shí),將CPU交給其他線程使用,從而很大地提高了CPU的利用效率,在多線程之間進(jìn)行更好的切換。
4) 多線程資源利用沖突問題解決
多線程通信中,對(duì)共享資源的訪問是必不可少的,因此,使用好同步鎖機(jī)制至關(guān)重要。例如在連接對(duì)象列表中通過下標(biāo)對(duì)某個(gè)終端發(fā)送數(shù)據(jù)時(shí),此時(shí)可能有新的終端連接對(duì)象不斷插入到列表中,造成下標(biāo)訪問的元素并非此前的元素,發(fā)生混亂,因此需要通過同步鎖機(jī)制,在操作某個(gè)連接對(duì)象時(shí),將整個(gè)連接對(duì)象隊(duì)列進(jìn)行鎖定,處理完成后再解鎖,保證通信操作的正確性[11]。
5) 系統(tǒng)持續(xù)穩(wěn)定檢測(cè)問題解決
陰極保護(hù)無線終端監(jiān)控系統(tǒng)要求長(zhǎng)期穩(wěn)定的工作,為了防止通信服務(wù)器死機(jī)或者人為關(guān)閉,開發(fā)了監(jiān)測(cè)小程序,通過監(jiān)測(cè)進(jìn)程管理器和定時(shí)發(fā)送反饋消息監(jiān)控通信服務(wù)器的運(yùn)行狀態(tài),一旦發(fā)現(xiàn)異常,殺掉現(xiàn)有進(jìn)程,重新啟動(dòng)新的通信服務(wù)程序。
在多線程TCP通信在陰保軟件系統(tǒng)中得到了成功的應(yīng)用,可以給同類型的應(yīng)用提供很好的借鑒和幫助。同時(shí),隨著設(shè)備數(shù)量的不斷增大,相應(yīng)進(jìn)程數(shù)量也會(huì)不斷增大,造成內(nèi)存和CPU資源的不斷上升。因此可以考慮進(jìn)行細(xì)粒度化的并發(fā)線程控制,可以讓一個(gè)獨(dú)立線程控制多個(gè)終端的數(shù)據(jù)通信;也可以采用線程隊(duì)列,使用CPU輪流為通信服務(wù),提高通信效率和并發(fā)效果。
參 考 文 獻(xiàn)
[1] 薛致遠(yuǎn),畢武喜,陳振華,等.油氣管道陰極保護(hù)技術(shù)現(xiàn)狀與展望[J].油氣儲(chǔ)運(yùn),2014,33(9):938-944.
XUE Zhiyuan, BI Wuxi, CHEN Zhenhua, et al. Situation and outlook for cathodic protectiontechnology of oil & gas pipeline[J]. Oil & Gas Storage and Transportation,2014,33(9):938-944.
[2] 沈明,蒲保興,唐彬.基于Windows套接字編程的網(wǎng)絡(luò)編碼仿真實(shí)現(xiàn)[J].軟件,2012,33(2):11-14.
SHEN Ming, PU Baoxing, TANG Bin. Simulation Implementation of Network Coding Based on Windows Socket Programming[J]. Software,2012,33(2):11-14.
[3] 張維承,王勇,陳抗生.原始套接字編程在嵌入式Internet通信協(xié)議中的應(yīng)用[J].計(jì)算機(jī)應(yīng)用研究,2002(10):29-30.
ZHANG Weicheng, WANG Yong, CHEN Kangsheng. The Application of Raw Socket Programmingin Embedded Internet Communication Protocol[J]. Application Research of Computers,2002(10):29-30.
[4] 高立江.即時(shí)通訊系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[D].成都:電子科技大學(xué),2012:10-14.
GAO Lijiang. Design and implementation of real-time communication system[D]. Chengdu: University of Electronic Science and Technology of China,2012:10-14.
[5] 張華.基于Vxworks的TCP/IP網(wǎng)絡(luò)通信設(shè)計(jì)在車載武器系統(tǒng)中的應(yīng)用[J].計(jì)算機(jī)與數(shù)字工程,2012,40(8):152-154.
ZHANG Hua. TCP/IP NetWork Communication Dseign Based on Vxworks in Vehicle-mounted Weapon System[J]. Computer & Digital Engineering,2012,40(8):152-154.
[6] 孫曉夢(mèng),王志斌.基于TCP的多線程Socket通信實(shí)例[J].遼東學(xué)院學(xué)報(bào)(自然科學(xué)版),2013,20(3):178-182.
SUN Xiaomeng, WANG Zhibin. A TCP—Based Multithread Socket Communication System[J]. Liaodong University(Natural Science),2013(3):178-182.
[7] 董方秀,鄧忠華.一種改進(jìn)的TCP擁塞控制算法及仿真[J].計(jì)算機(jī)與數(shù)字工程,2012,40(11):77-78.
DONG Fangxiu, DENG Zhonghua. An Improved TCP Congestion Control Algorithm and Simulation[J]. Computer & Digital Engineering,2012,40(11):76-78.
[8] 陳小輝,劉心松,等.分布式并行數(shù)據(jù)庫中基于調(diào)度的多線程通信模型之研究[J].小型微型計(jì)算機(jī)系統(tǒng),2005,26(4):604-608.
CHEN Xiaohui, LIU Xinsong, et al. Study on Multithreaded-Communication-Model Based on Scheduling in Distributedand Parallel Data base System[J]. Journal of Chinese Computer Systems,2005,26(4):604-608.
[9] 羅亞非.基于TCP的Socket多線程通信[J].電腦知識(shí)與技術(shù),2009,5(3):563-565.
LUO Yafei. The Multi-thread Communication of Socket Based on TCP[J]. Computer Knowledge and Technology,2009,5(3):563-565.
[10] 賈廣雷,劉培玉,耿長(zhǎng)欣,等.多線程技術(shù)及其在串口通信中的應(yīng)用[J].計(jì)算機(jī)工程,2003,29(1):247-249.
JIA Guanglei, LIU Peiyu, GENG Changxin, et al. Multithread Technology and Its Application on Serial Communication[J]. Computer Engineering,2003,29(1):247-249.
[11] 成衛(wèi)青,王雪梅,豆仁福,等.三種基本網(wǎng)絡(luò)傳送模式的編程實(shí)現(xiàn)與分析[J].計(jì)算機(jī)技術(shù)與發(fā)展,2011,21(7):132-137.
CHENG Weiqing, WANG Xuemei, DOU Renfu, et al. Three Basic Transfer Mode Network Programming and Analysis[J]. Computer Technology and Development,2011,21(7):132-137.
收稿日期:2015年10月7日,修回日期:2015年11月28日
基金項(xiàng)目:運(yùn)城學(xué)院院級(jí)項(xiàng)目(編號(hào):CY-2013016)資助。
作者簡(jiǎn)介:盧照,男,碩士研究生,助教,研究方向:并行計(jì)算及信息處理。
中圖分類號(hào)TP393.1
DOI:10.3969/j.issn.1672-9722.2016.04.032
Application of Multi-thread Socket Communication Based on TCP in Cathodic Protection Software
LU ZhaoHE Zhilin
(Computer Science and Technology Department, Yuncheng University, Yuncheng044000)
AbstractCommunication service software is an important part of cathodic protection software system, real-time, accuracy and efficiency of communication directly affect the entire cathodic protection software performance and decision-making. .NET Framework Socket class is socket services Winsock32 API. To achieve network programming, a number of methods are provided, with the Socket class network program will be very easy. Software uses multi-threading technology, using a TCP socket communication, and applied to the actual cathodic protection software system to achieve real-time communication between the terminal device and the server, for the cathodic protection software provides real-time data information, played on terminal equipment status in real-time monitoring role. Systems in practical applications and real-time stability are relatively satisfactory.
Key Wordsnetwork communication, multi-threaded, Socket, TCP