亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于Qt的一個(gè)服務(wù)器多個(gè)客戶(hù)端的TCP通信

        2015-12-20 01:09:54翩,張瓊,祝
        電子科技 2015年3期
        關(guān)鍵詞:信號(hào)

        黃 翩,張 瓊,祝 婷

        (西安電子科技大學(xué)電子信息攻防對(duì)抗與仿真重點(diǎn)實(shí)驗(yàn)室,陜西西安 710071)

        目前大多數(shù)智能設(shè)備和儀表均采用RS232/485的通信方式,不具備遠(yuǎn)程控制和數(shù)據(jù)傳輸能力,而如何利用以太網(wǎng)實(shí)現(xiàn)遠(yuǎn)程通信則是問(wèn)題的關(guān)鍵。近年來(lái),以TCP/IP為基礎(chǔ)的面向數(shù)據(jù)流和連接的可靠傳輸協(xié)議得到迅猛發(fā)展,但傳統(tǒng)的軟件開(kāi)發(fā)方法是利用Socket套接字來(lái)編寫(xiě)程序,因?yàn)槠涮捉幼直容^復(fù)雜,包含了許多的數(shù)據(jù)結(jié)構(gòu)和函數(shù),難以掌握和使用。而Qt把網(wǎng)絡(luò)編程有關(guān)的數(shù)據(jù)結(jié)構(gòu)和函數(shù)封裝成類(lèi),在較大程度上模塊化,于是軟件開(kāi)發(fā)的程序變得簡(jiǎn)潔、高效,可重用性較好,用戶(hù)開(kāi)發(fā)非常方便。

        1 TCP通信原理

        傳輸控制協(xié)議(Transmission Control Protocol,TCP)是一個(gè)用于數(shù)據(jù)傳輸?shù)牡蛯泳W(wǎng)絡(luò)協(xié)議,多個(gè)互聯(lián)網(wǎng)協(xié)議都是基于TCP協(xié)議的。TCP是一個(gè)面向數(shù)據(jù)流和連接的可靠傳輸協(xié)議[1],對(duì)于應(yīng)用程序來(lái)說(shuō),數(shù)據(jù)是一個(gè)較長(zhǎng)的流,因此在TCP上建立的高層協(xié)議通常是面向塊(Block-oriented)或面向行的(Line-oriented)。面向塊的協(xié)議把數(shù)據(jù)作為二進(jìn)制塊傳輸,每個(gè)數(shù)據(jù)塊由一個(gè)大小字段和包含的數(shù)據(jù)組成。面向行的協(xié)議把數(shù)據(jù)作為一個(gè)文本文件的行來(lái)傳輸,每一個(gè)數(shù)據(jù)行都以一個(gè)換行符結(jié)束。

        1.1 TCP/IP協(xié)議

        在TCP/IP協(xié)議中,TCP協(xié)議提供可靠的連接服務(wù),采用3次握手建立一個(gè)連接[2]:

        第一次握手:建立連接時(shí),客戶(hù)端發(fā)送 SYN包(SYN=j)到服務(wù)器,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器確認(rèn);

        第二次握手:服務(wù)器收到SYN包,必須確認(rèn)客戶(hù)的SYN(ACK=j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(SYN=k),即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);

        第三次握手:客戶(hù)端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ACK=k+1),此包發(fā)送完畢,客戶(hù)端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài),完成3次握手。

        完成3次握手,客戶(hù)端和服務(wù)器開(kāi)始傳送數(shù)據(jù)。

        1.2 TCP Socket通信工作原理

        TCP Socket的通信工作原理[6]如圖1所示。

        圖1 TCPSocket通信原理圖

        客戶(hù)端首先通過(guò)調(diào)用Socket()函數(shù)創(chuàng)建TCP套接口,指定服務(wù)器IP地址和端口,然后調(diào)用connect()函數(shù)與服務(wù)器取得連接,接著進(jìn)行數(shù)據(jù)處理,讀入并輸出客戶(hù)端的應(yīng)答,最后關(guān)閉程序。

        服務(wù)器端也是通過(guò)調(diào)用Socket()函數(shù)來(lái)創(chuàng)建TCP套接口,用bind函數(shù)將Socket與主機(jī)信息進(jìn)行綁定,然后通過(guò)listen()函數(shù)監(jiān)聽(tīng)客戶(hù)端的連接,accept()接受客戶(hù)端的連接后進(jìn)行數(shù)據(jù)處理,讀入并輸出服務(wù)器的應(yīng)答,最后終止程序。

        2 Qt中與TCP有關(guān)的類(lèi)

        Qt中與 TCP有關(guān)的類(lèi)主要有 QTCPServer類(lèi)、QTCPSocket類(lèi)和QHostAddress類(lèi),由于QTCPSocket類(lèi)繼承自 QIODevice。所以,其可從 QDataStream或QTextStream中讀取或?qū)懭霐?shù)據(jù),而且從文件讀數(shù)據(jù)和從網(wǎng)絡(luò)上讀數(shù)據(jù)有一個(gè)明顯的不同:必須保證用操作符“?”讀取數(shù)據(jù)時(shí),已從另一方接收了足夠的數(shù)據(jù)。如果沒(méi)有做到這點(diǎn),那么則會(huì)有一個(gè)失敗的結(jié)果:行為未定義。此外,QTCPServer類(lèi)和QTCPSocket類(lèi)需要事件機(jī)制支持,故要在程序中開(kāi)啟事件循環(huán)或調(diào)用相應(yīng)的事件響應(yīng)函數(shù)。

        2.1 關(guān)于QTCPSocket類(lèi)

        QTCPSocket類(lèi)為T(mén)CP提供了一個(gè)接口,繼承自QAbstractSocket。可以使用QTCPSocket來(lái)實(shí)現(xiàn)POP3、SMTP和NNTP等標(biāo)準(zhǔn)網(wǎng)絡(luò)協(xié)議,也可實(shí)現(xiàn)自定義的網(wǎng)絡(luò)協(xié)議。QTCPSocket傳輸?shù)氖沁B續(xù)的數(shù)據(jù)流,尤其適合連續(xù)的數(shù)據(jù)傳輸[1]。

        在數(shù)據(jù)傳輸前,必須建立一個(gè)TCP連接到遠(yuǎn)程的主機(jī)和端口,可以使用connectToHost()函數(shù)與服務(wù)器進(jìn)行連接,該函數(shù)有兩種重載形式,一種使用字符串來(lái)表示主機(jī)地址的參數(shù)類(lèi)型,一種是用QHostAddress類(lèi)。一旦建立連接,將返回一個(gè)connected()信號(hào),如果出現(xiàn)錯(cuò)誤,將返回 error(QAbstractSocket::SocketError socketError)信號(hào),socketError參數(shù)描述錯(cuò)誤的類(lèi)型。

        連接成功后便可根據(jù)需要發(fā)送或接收數(shù)據(jù)??墒褂脀rite()寫(xiě)入數(shù)據(jù),使用read()讀取數(shù)據(jù)。當(dāng)QTCPSocket收到新的數(shù)據(jù)時(shí),readyRead()信號(hào)就會(huì)被發(fā)送。將該信號(hào)與處理該信號(hào)的槽函數(shù)相連,實(shí)現(xiàn)相應(yīng)的功能。但是該信號(hào)被發(fā)送時(shí),并不代表數(shù)據(jù)已經(jīng)被完整接收,接收到的可能是一包不完整的數(shù)據(jù)、一包完整的數(shù)據(jù)或若干包完整的數(shù)據(jù)和一包不完整的數(shù)據(jù)、若干包完整的數(shù)據(jù)等多種情況,所以在處理數(shù)據(jù)時(shí)要考慮所有的情況,以免錯(cuò)誤地去解析數(shù)據(jù)[1]。從一個(gè)QTCPSocket中讀取數(shù)據(jù)前,必須先調(diào)用bytesAvailable()函數(shù)來(lái)確保已有足夠數(shù)據(jù)可用。

        最后可使用disconnectFromHost()函數(shù)來(lái)斷開(kāi)與服務(wù)器的連接。使用QTCPSocket類(lèi)實(shí)現(xiàn)客戶(hù)端的流程如圖2所示。

        圖2 QTCPSocket類(lèi)實(shí)現(xiàn)客戶(hù)端流程

        服務(wù)器端也需要 QTCPSocket才能與客戶(hù)端的QTCPSocket建立一個(gè)TCP連接。不同之處在于服務(wù)器端QTCPSocket的創(chuàng)建是在服務(wù)器監(jiān)聽(tīng)到連接請(qǐng)求時(shí)進(jìn)行的。

        2.2 關(guān)于QTCPServer類(lèi)

        QTCPServer類(lèi)可用來(lái)處理到來(lái)的TCP連接,值得注意的是,該類(lèi)直接繼承于 QObject基類(lèi),而不是QAbstractSocket抽象套接字類(lèi)。其調(diào)用listen()設(shè)置服務(wù)器,監(jiān)聽(tīng)某一地址和端口,然后關(guān)聯(lián)newConnection()信號(hào),當(dāng)收到客戶(hù)端連接請(qǐng)求時(shí)就發(fā)射該信號(hào)。在槽中,調(diào)用nextPendingConnection()來(lái)接受這個(gè)連接,然后創(chuàng)建一個(gè)QTCPSocket對(duì)象與客戶(hù)端進(jìn)行通信。

        3 基于Qt的TCP通信的算法實(shí)現(xiàn)

        以雷達(dá)信號(hào)環(huán)境模擬器的上位機(jī)與下位機(jī)的TCP通信為例,上位機(jī)相當(dāng)于服務(wù)器,下位機(jī)則是客戶(hù)端。雷達(dá)信號(hào)環(huán)境模擬器有5個(gè)不同頻段的雷達(dá),相當(dāng)于5個(gè)不同的客戶(hù)端,服務(wù)器端監(jiān)聽(tīng)客戶(hù)端的接連,當(dāng)客戶(hù)端連接上服務(wù)器時(shí),服務(wù)器首先給客戶(hù)端發(fā)送一個(gè)詢(xún)問(wèn)幀,客戶(hù)端回答應(yīng)答幀;接著服務(wù)器發(fā)送自檢命令,客戶(hù)端響應(yīng)自檢命令,回送自檢結(jié)果;最后服務(wù)器發(fā)送雷達(dá)參數(shù)幀。

        3.1 實(shí)現(xiàn)的功能

        (1)開(kāi)啟服務(wù)器,支持多客戶(hù)端接入,能夠?qū)崟r(shí)顯示每個(gè)客戶(hù)端接入狀態(tài)。

        (2)等待所有客戶(hù)端都處于連接狀態(tài)時(shí),向各個(gè)客戶(hù)端發(fā)送數(shù)據(jù)。

        (3)發(fā)送完成后等待客戶(hù)端回復(fù),顯示回復(fù)結(jié)果。

        (4)通信完成,關(guān)閉服務(wù)器。

        3.2 支持多客戶(hù)端的服務(wù)器的主要算法實(shí)現(xiàn)

        (1)新建服務(wù)器類(lèi)TCPServer和TCPSocket類(lèi),分別繼承自QTCPServer和QTCPSocket。新建服務(wù)器類(lèi)TCPServer用于接收客戶(hù)端的TCP請(qǐng)求,存儲(chǔ)所有客戶(hù)端信息,并向主窗口發(fā)送信息。在這個(gè)類(lèi)中最關(guān)鍵的是實(shí)例化QTCPServer中的虛函數(shù):void incomingConnection(int socketDescriptor),重寫(xiě)這個(gè)虛函數(shù),有TCP請(qǐng)求時(shí)會(huì)觸發(fā),參數(shù)為描述socket ID的int變量,此函數(shù)在QTCPServer檢測(cè)到外來(lái) TCP請(qǐng)求時(shí),會(huì)自動(dòng)調(diào)用[3-4]。

        新建TCPSocket類(lèi),控制發(fā)送/接收數(shù)據(jù),向TCPS-erver發(fā)送相關(guān)信號(hào)。在TCPServer類(lèi)的incomingConnection(int socketDescriptor)函數(shù)中,通過(guò)設(shè)置Socket-Descriptor,初始化一個(gè) TCPSocket實(shí)例[4],具體實(shí)現(xiàn)如圖3所示。

        圖3 incomingConnection()函數(shù)的實(shí)現(xiàn)

        上述newConnection()信號(hào)是接收到局域網(wǎng)內(nèi)的TCP請(qǐng)求后,連接此信號(hào)到自定義的槽函數(shù)connect(TCPServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));但這只針對(duì)一個(gè)客戶(hù)端的情況,無(wú)法處理多客戶(hù)端。

        TCPSocket類(lèi),連接有 readyRead()信號(hào),ready-Read()信號(hào)為新連接中有可讀數(shù)據(jù)時(shí)發(fā)出:connect(this,SIGNAL(readyRead()),this,SLOT(emitready-Read()));

        在emitreadyRead()的槽函數(shù)中發(fā)出一個(gè)讀信號(hào)給TCPServer:

        void TCPSocket::emitreadyRead()

        {

        emit readyReadSocket((QTCPSocket*)this);

        }

        (2)接收/發(fā)送數(shù)據(jù)的算法實(shí)現(xiàn)。連接建立好后便可進(jìn)行數(shù)據(jù)的接收與發(fā)送。在TCPServer中將TCPSocket發(fā)送的readyReadSocket((QTCPSocket*)this)信號(hào)連接給槽函數(shù)readMessage(QTCPSocket*)進(jìn)行數(shù)據(jù)讀取,算法實(shí)現(xiàn)如圖4所示。

        圖4 readMessage()的實(shí)現(xiàn)算法

        通過(guò)點(diǎn)擊界面上的發(fā)送數(shù)據(jù)按鈕觸發(fā)槽函數(shù)sendMessage(char*)發(fā)送數(shù)據(jù),算法實(shí)現(xiàn)如圖 5所示。

        圖5 sendMessage()的實(shí)現(xiàn)算法

        綜上所述,完成此服務(wù)器的搭建,建立了Server類(lèi)、TCPServer類(lèi)和 TCPSocket類(lèi)。Server類(lèi)繼承自QWidget,主要完成界面上的功能,實(shí)現(xiàn)人機(jī)交互;TCPServer類(lèi)主要完成接收客戶(hù)端的連接請(qǐng)求,進(jìn)行數(shù)據(jù)的接收和發(fā)送;TCPSocket類(lèi)主要完成套接字的創(chuàng)建。這3類(lèi)之間有些信號(hào)是相互關(guān)聯(lián)的,所以這3類(lèi)層層相扣,缺一不可。完整工程如圖6所示。

        圖6 建立完整的工程

        4 結(jié)束語(yǔ)

        Qt對(duì)Socket的封裝,方便了開(kāi)發(fā)人員,且Qt還提供了一種signals/slots的信號(hào)槽機(jī)制,用這種安全類(lèi)型來(lái)替代callback(回調(diào)),這使各元件之間的協(xié)同工作變得簡(jiǎn)單。同時(shí)Qt是源代碼級(jí)的跨平臺(tái),一次編寫(xiě),隨處編譯,一次開(kāi)發(fā)的Qt應(yīng)用程序可以移植到不同平臺(tái)上,只需重新編譯即可運(yùn)行[5]。這樣也減少了開(kāi)發(fā)者在開(kāi)發(fā)不同平臺(tái)下應(yīng)用程序的工作量?;赒t的這些優(yōu)點(diǎn),可預(yù)見(jiàn)Qt將被更多開(kāi)發(fā)人員推崇,其應(yīng)用將不斷擴(kuò)展。

        [1]霍亞飛.QtCreator快速入門(mén)[M].北京:北京航空航天大學(xué)出版社,2012.

        [2]LAURA A.Chappell,Ed Tittel.TCP/IP 協(xié)議原理與應(yīng)用[M].北京:清華大學(xué)出版社,2009.

        [3]Nokia公司.Qt參考文檔[EB/OL].(2011-11-13)[2014 -04 -11]http://doc.trolltech.com/5.0/index.html

        [4]Jasmin Blanchette,Mark Summerfield.C++GUI Qt4 編程[M].2 版.北京:電子工業(yè)出版社,2008.

        [5]蔡志明,盧傳富,李立夏.精通Qt4編程[M].北京:電子工業(yè)出版社,2008.

        [6]趙偉.基于Socket的消息隊(duì)列中間件的研究與實(shí)現(xiàn)[D].呼和浩特:內(nèi)蒙古大學(xué),2007.

        [7]郭春柱.嵌入式系統(tǒng)設(shè)計(jì)師案例導(dǎo)學(xué)[M].西安:西安電子科技大學(xué)出版社,2007.

        [8]么麗穎.基于Linux的服務(wù)器集群系統(tǒng)的研究與設(shè)計(jì)[J].電子科技,2012,25(6):4 -5,26.

        猜你喜歡
        信號(hào)
        信號(hào)
        鴨綠江(2021年35期)2021-04-19 12:24:18
        完形填空二則
        7個(gè)信號(hào),警惕寶寶要感冒
        媽媽寶寶(2019年10期)2019-10-26 02:45:34
        孩子停止長(zhǎng)個(gè)的信號(hào)
        《鐵道通信信號(hào)》訂閱單
        基于FPGA的多功能信號(hào)發(fā)生器的設(shè)計(jì)
        電子制作(2018年11期)2018-08-04 03:25:42
        基于Arduino的聯(lián)鎖信號(hào)控制接口研究
        《鐵道通信信號(hào)》訂閱單
        基于LabVIEW的力加載信號(hào)采集與PID控制
        Kisspeptin/GPR54信號(hào)通路促使性早熟形成的作用觀察
        亚洲va久久久噜噜噜久久男同| 国产精女同一区二区三区久| 精品亚洲第一区二区三区| 精品成在人线av无码免费看| 亚洲av无码一区二区乱子伦as| a欧美一级爱看视频| 精品黄色国产一区二区| 加勒比一本heyzo高清视频| 中文字幕无码av激情不卡| av少妇偷窃癖在线观看| 老岳肥屁熟女四五十路| 亚洲av无码专区在线| 日本一区二区在线免费视频| 免费毛片a线观看| 欧美三级不卡视频| 婷婷开心五月综合基地| 国产精品亚洲三级一区二区三区| 中文人妻熟女乱又乱精品| 国产大学生粉嫩无套流白浆| 久久中文字幕亚洲精品最新| 亚洲精品中文字幕一二三| 97人人模人人爽人人喊网| 99re久久精品国产| 日本亚洲一级中文字幕| 宅男亚洲伊人久久大香线蕉| 国产中文字幕乱人伦在线观看| 啪啪无码人妻丰满熟妇| 精品人妻av一区二区三区不卡| 精品一区二区三区久久| 国产白嫩护士被弄高潮| 一区二区三区日韩亚洲中文视频| 亚洲中文字幕日本日韩| 丰满少妇人妻无码| 理论片87福利理论电影| 无码人妻专区免费视频| 国产少妇露脸精品自拍网站| 国产精品成熟老女人| 久久久久久久99精品国产片| 国产激情视频免费观看| 久久精品国产亚洲av网| 野花社区视频www官网|