春有百花秋有月出吹,夏有涼風冬有雪。若無閑事掛心頭辙喂,便是人間好時節(jié)捶牢。
一、 前言
??我之前寫過一篇帖子:【LabVIEW開發(fā)】如何使用LabVIEW進行TCP通信巍耗?秋麸,里面比較詳細地介紹了在LabVIEW的開發(fā)環(huán)境下如何與第三方進行TCP通信,內(nèi)容比較基礎(chǔ)炬太,感興趣的可以去看看灸蟆。
??當時寫完這篇帖子,我就樂呵呵的以為這是LabVIEW進行TCP通信的終極形態(tài)亲族,直到現(xiàn)實給了我當頭一棒炒考。在后來的一次項目中,我用LabVIEW開發(fā)上位機霎迫,使用TCP協(xié)議與西門子S7-1200進行數(shù)據(jù)通信票腰,一開始在家做調(diào)試的時候上位機軟件沒啥問題,直到有一次在項目現(xiàn)場調(diào)試設(shè)備的時候女气,發(fā)現(xiàn)下位機上傳給上位機軟件的參數(shù)都沒了杏慰,一檢查發(fā)現(xiàn):與工控主機連接的PLC網(wǎng)口的網(wǎng)線松動,就把網(wǎng)線重新插好炼鞠,但是軟件依然沒有接收硬件上傳的數(shù)據(jù)缘滥,這時我才意識到自己寫的上位機軟件沒有斷線重連功能。
??這個問題雖然可以通過重啟軟件來解決谒主,重啟軟件后通信恢復了朝扼,但依然說明我寫的TCP通信程序是由缺陷的。既然發(fā)現(xiàn)了問題霎肯,當然要解決問題擎颖,不然跟咸魚有什么區(qū)別榛斯。在網(wǎng)上查閱了大量資料后,終于找到了一位大佬寫的程序完美的解決了這個問題搂捧,我覺得有必要把他貼出來:
??也許是LabVIEW版本不同或者操作系統(tǒng)不一樣的原因驮俗,這位大佬給的源程序在我的電腦上運行時會報一些小錯誤,而且程序面板里的連線縱橫交錯(估計是版本不同導致的)允跑,不利于基礎(chǔ)相對較差的人閱讀和修改王凑。為此我在源程序的基礎(chǔ)上重新寫了一個相對精簡的程序,并成功實現(xiàn)了TCP通信的斷線重連功能聋丝。
二索烹、 實戰(zhàn)練習
1、編程思路
??具體實現(xiàn)程序的編寫思路是:使用TCP客戶端/服務(wù)端單獨與網(wǎng)絡(luò)調(diào)試助手進行通信弱睦,通信成功后百姓,手動點擊網(wǎng)絡(luò)調(diào)試助手界面上的“斷開連接”按鈕,此時LabVIEW與網(wǎng)絡(luò)調(diào)試助手通信斷開况木,數(shù)據(jù)無法收發(fā)瓣戚;然后再手動點擊網(wǎng)絡(luò)調(diào)試助手界面的上“打開連接”按鈕,觀察之前斷開的TCP連接是否重新連接焦读,收據(jù)是否可以收發(fā)。
??網(wǎng)絡(luò)調(diào)試助手主要是用來模擬第三方具備以太網(wǎng)通信功能的硬件設(shè)備舱权,比如個人PC矗晃、PLC、單片機等宴倍。如果與網(wǎng)絡(luò)調(diào)試助手通信正常张症,那么與其他硬件進行TCP通信也就不會有什么問題。后期有時間我會用LabVIEW與西門子PLC通信鸵贬,然后重啟PLC俗他,看TCP通信是否會斷線重連。
2阔逼、Client端斷線重連
??客戶端的前面板只有字符串顯示框兆衅,用來顯示網(wǎng)絡(luò)調(diào)試助手發(fā)過來的數(shù)據(jù);程序面板與我之前寫的如何使用LabVIEW進行TCP通信嗜浮?中所寫基本一樣羡亩,最大的區(qū)別是使用移位寄存器,然后為了讓網(wǎng)絡(luò)調(diào)試助手接收的每一幀數(shù)據(jù)是變化的危融,發(fā)送數(shù)據(jù)改用隨機數(shù)生成的數(shù)組轉(zhuǎn)化為字符串后進行發(fā)送畏铆,而不是手動輸入。
??client端程序?qū)崿F(xiàn)斷線重連的核心原理是:通過判斷TCP模塊輸出的錯誤代碼是否等于66或63吉殃,如果通信異炒蔷樱或斷開楷怒,條件為真進入到條件結(jié)構(gòu)里的順序結(jié)構(gòu)部分,順序結(jié)構(gòu)依次為斷開TCP連接瓦灶、延遲3秒鸠删、重新打開TCP連接。如果此時網(wǎng)絡(luò)調(diào)試助手server端恢復正常倚搬,那么client端的通信就恢復了冶共,也就實現(xiàn)了斷線重連。
??如果第三方server端一直沒有打開監(jiān)聽每界,那么TCP模塊的錯誤代碼會一直是66或63捅僵,那么程序就會每隔3秒進行重連操作,直到通信恢復正常眨层。在多次重復測試中庙楚,我發(fā)現(xiàn)錯誤代碼一直都是66,一次也沒檢測到63趴樱,可能是測試次數(shù)不夠未能檢測到馒闷,建議兩個數(shù)字都用。至于TCP通信異常的錯誤代碼為啥是66或者63叁征,說實話我也不知道纳账,這可能要去問NI公司的軟件開發(fā)工程師了。
??具體的實現(xiàn)程序如下圖所示:
??下面再來看下程序運行的結(jié)果捺疼,將網(wǎng)絡(luò)調(diào)試助手設(shè)置為server型疏虫,IP和Port分別設(shè)置為127.0.0.1和6666。此時啤呼,不管是先運行LabVIEW的client端程序卧秘,還是先運行調(diào)試助手的server端程序,雙端之間都可以正常進行TCP通信官扣。由于我在client端的TCP read模塊設(shè)置的接收數(shù)據(jù)字節(jié)數(shù)為4翅敌,所以調(diào)試助手發(fā)送的數(shù)據(jù)是4個字節(jié),目前client端程序無法自動獲取接收數(shù)據(jù)的字節(jié)數(shù)惕蹄,需要手動設(shè)置蚯涮。程序具體運行結(jié)果如下圖所示:
??此時點擊調(diào)試助手上的“斷開”按鈕,可以看到client端前面板的字符串顯示框中的數(shù)據(jù)消失了卖陵,說明此時軟件沒有接收到數(shù)據(jù)恋昼,通信已中斷;然會再點擊調(diào)試助手界面上的“打開”按鈕赶促,然后點擊發(fā)送數(shù)據(jù)液肌,雙端之間的通信自動恢復正常。同樣鸥滨,保持server端運行嗦哆,中斷client程序運行谤祖,然后重新運行client程序,TCP通信依舊可以自動恢復老速。
3粥喜、Server端斷線重連
??server端的前面板是一個字符串顯示框和一個停止按鈕,分別用來顯示調(diào)試助手發(fā)送的數(shù)據(jù)和關(guān)閉程序橘券。程序面板編寫的核心原理是:
??首先設(shè)置"TCP Listen.vi"模塊的端口為6666额湘,通信超時設(shè)置為0,然后判斷該模塊輸出的錯誤狀態(tài)碼旁舰,通信正常時狀態(tài)碼為0锋华,通信異常時狀態(tài)碼為1。也就是說箭窜,當client端通信中斷后毯焕,server端偵聽模塊的狀態(tài)碼就變?yōu)?,錯誤碼會變?yōu)?2或者66磺樱,而條件結(jié)構(gòu)“真”里面的代碼為空纳猫,此時程序開始執(zhí)行外部大循環(huán)里偵聽模塊的程序,與此同時竹捉,條件結(jié)構(gòu)中的小循環(huán)讀/寫程序被中止芜辕。
??經(jīng)過我多次測試,發(fā)現(xiàn)錯誤碼大部分時候是62块差,少數(shù)情況下會出現(xiàn)66侵续,所以這兩個數(shù)必須要使用。具體的實現(xiàn)程序如下圖所示:
??如果client端打開連接憾儒,server端一旦偵聽到了該連接,通信恢復正常乃沙,狀態(tài)碼和錯誤碼會立刻轉(zhuǎn)變?yōu)?起趾,數(shù)據(jù)就可以正常收發(fā)。與我之前寫的基本版通信程序相比警儒,這個程序最大的改變就是client端通信中斷后训裆,會不斷循環(huán)運行“TCP Listen.vi”這個模塊,進行循環(huán)監(jiān)聽蜀铲;而基本版的程序只進行過一次監(jiān)聽边琉,如果中途通信斷掉了,這個偵聽模塊不會再重新運行记劝,也就不能實現(xiàn)斷線重連变姨。
??程序運行的結(jié)果如下圖所示:
??先運行server端程序,然后將調(diào)試助手設(shè)置為Client模式厌丑,并設(shè)置好IP和Port定欧,點擊面板上的“連接”按鈕渔呵,調(diào)試助手立馬顯示同行已連接,再點擊循環(huán)發(fā)送按鈕砍鸠,數(shù)據(jù)就可以正常收發(fā)扩氢。為了方便觀察,我把調(diào)試助手的循環(huán)發(fā)送周期設(shè)置為1.5s爷辱。
??依次點擊調(diào)試助手面板上的“斷開”--“連接”--“發(fā)送”录豺,模擬客戶端連接中斷(網(wǎng)線拔掉),重新連接(網(wǎng)線插上)的過程饭弓,可以看到與server端的通信馬上就恢復了双饥,說明上述程序?qū)崿F(xiàn)了斷線重連功能。
??
三示启、 小結(jié)
??1兢哭、數(shù)據(jù)收發(fā)的周期一般是雙端匹配的,不管我上位機軟件收發(fā)周期設(shè)置為多少毫秒夫嗓,下位機硬件的發(fā)送周期如果比上位機的接收周期長迟螺,就會以時間更長的一端為準。這個在實際的項目中需要注意一下舍咖。
??2矩父、軟件沒有自動識別接收數(shù)據(jù)字節(jié)數(shù)的功能,所以在read模塊需要設(shè)置好接收數(shù)據(jù)的字節(jié)數(shù)排霉,并與調(diào)試助手上發(fā)送的數(shù)據(jù)字節(jié)數(shù)保持一致窍株。如果不一致,會導致數(shù)據(jù)無法接收揮著接收數(shù)據(jù)亂碼攻柠。