久久―日本道色综合久久,亚洲欧美精品在线,狼狼色丁香久久婷婷综合五月,香蕉人人超,日本网站黄,国产在线观看不卡免费高清,无遮挡的毛片免费

2025年度未來銀行科技服務(wù)商TOP100
全世界各行各業(yè)聯(lián)合起來,internet一定要實現(xiàn)!

VB6實現(xiàn)局域網(wǎng)多站點互連手冊

2004-02-23 eNet&Ciweek

  這里對Winsock控件的屬性、方法和事件的介紹限于篇幅就不介紹了,下面以最簡單的C/S模式下一臺服務(wù)器和一臺客戶機(jī)的連接來說明其整個連接過程。

  用框圖表示如圖1所示。首先運行服務(wù)器端的程序,使TcpServer處于監(jiān)聽狀態(tài),然后運行客戶機(jī)端的程序,單擊【連接服務(wù)器】按鈕后,客戶機(jī)端調(diào)用Connect方法呼叫服務(wù)器(根據(jù)RemoteHostIP遠(yuǎn)程計算機(jī)IP地址和RemotePort遠(yuǎn)程計算機(jī)端口號兩個參數(shù)),然后客戶機(jī)便處于正在連接服務(wù)器狀態(tài),等待服務(wù)器的響應(yīng)。客戶機(jī)調(diào)用Connect方法觸發(fā)了服務(wù)器ConnectRequest事件,這時服務(wù)器端可以在此事件中判斷是否要接受客戶機(jī)的請求,如要就調(diào)用Accept方法,并置標(biāo)志位說明已成功連接客戶機(jī)。服務(wù)器端調(diào)用Accept方法后又觸發(fā)了客戶機(jī)端Connect事件,說明服務(wù)器端接受客戶端的請求,雙方已經(jīng)建立連接了,這時再置客戶機(jī)端的標(biāo)志位,這就是一個完整的連接過程。當(dāng)服務(wù)器或客戶機(jī)調(diào)用Close方法關(guān)閉連接時,都會觸發(fā)對方的Close事件,使其關(guān)閉連接。另外建立連接后發(fā)送數(shù)據(jù)的情況是客戶機(jī)通過調(diào)用SendData方法發(fā)送數(shù)據(jù)給服務(wù)器,會觸發(fā)服務(wù)器端的DataArrival事件,在這個事件中,服務(wù)器端可以調(diào)用GetData或PeekData方法把客戶機(jī)發(fā)來的數(shù)據(jù)保存起來。服務(wù)器給客戶機(jī)發(fā)信息同理。要注意一點的是,在服務(wù)器的Close事件中應(yīng)該加上繼續(xù)監(jiān)聽的代碼,這樣客戶機(jī)才可以繼續(xù)呼叫服務(wù)器。



  Winsock控件實現(xiàn)多機(jī)互連方案

  下面是實現(xiàn)多機(jī)互連的三種方案。這里以三臺機(jī)(分別命名為1號機(jī)、2號機(jī)和3號機(jī))為例介紹。

  方案一:一臺機(jī)作為服務(wù)器,其余兩臺機(jī)作為客戶機(jī)

  1號機(jī)作為服務(wù)器,用一個Winsock控件數(shù)組負(fù)責(zé)監(jiān)聽客戶機(jī)的呼叫請求并用來與客戶機(jī)建立連接。用TcpServer(2)和TcpServer(3)兩個Winsock控件數(shù)組分別與2號機(jī)和3號機(jī)建立連接。

  這里采用的是動態(tài)加載和卸載Winsock控件數(shù)組來實現(xiàn)連接的,也就是服務(wù)器一定要開著,下面的客戶機(jī)才能與其通過Winsock控件實現(xiàn)通訊,當(dāng)服務(wù)器已經(jīng)與其中的一臺建立連接后,其它客戶機(jī)還要呼叫服務(wù)器時,服務(wù)器就會加載新的Winsock控件來與其建立連接,當(dāng)客戶機(jī)退出連接時,服務(wù)器再卸載該Winsock控件。服務(wù)器建立連接時是根據(jù)客戶機(jī)的IP地址來接受響應(yīng)的,所以可以方便的區(qū)分不同客戶機(jī)的呼叫請求。

  不過這種方案會遇到一些問題:比如只要服務(wù)器關(guān)閉,其它客戶機(jī)之間就無法進(jìn)行數(shù)據(jù)交換了,而在服務(wù)器開的情況下,可以通過服務(wù)器的轉(zhuǎn)發(fā)來完成客戶機(jī)之間的數(shù)據(jù)交換。

  方案二:三臺機(jī)同時作為服務(wù)器和客戶機(jī)

  1號機(jī)、2號機(jī)和3號機(jī)沒有層次等級之分,采用C/S模式。比如1號機(jī)既可以作為服務(wù)器接受其它兩臺機(jī)的呼叫請求,又可以作為客戶機(jī)對其它兩臺機(jī)進(jìn)行呼叫。用1號機(jī)做個比方:在1號機(jī)程序窗口中用兩個Winsock控件數(shù)組,分別命名為TcpServer和TcpClient,TcpServer(0)用來對客戶機(jī)進(jìn)行監(jiān)聽,TcpServer(2)和TcpServer(3)是動態(tài)加載用來接受相應(yīng)的客戶機(jī)的請求來建立連接的。而TcpClient(2)和TcpClient(3)不是動態(tài)加載的,而是在Form_Load初始化過程中加載,用來呼叫相應(yīng)的服務(wù)器。

  這樣也是可以實現(xiàn)多機(jī)互連的,不過也有些問題。如果1號機(jī)作為客戶機(jī)呼叫2號機(jī)并已經(jīng)收到2號機(jī)的響應(yīng)建立了一條通訊鏈路,這時1號機(jī)又作為服務(wù)器接收到2號機(jī)的呼叫請求,并且也建立了一條通訊鏈路。這樣二臺機(jī)之間建立了兩條鏈路,理論上兩臺機(jī)只要有一條鏈路就可以正常通訊,現(xiàn)在建立了兩條鏈路,收發(fā)數(shù)據(jù)是否正常呢?通過測試,收發(fā)數(shù)據(jù)不會出錯:當(dāng)1號機(jī)給2號機(jī)發(fā)數(shù)據(jù)時,是通過1號機(jī)的TcpServer(2)或TcpClient(2)發(fā)送數(shù)據(jù)給2號機(jī),而2號機(jī)是通過其TcpClient(1)或TcpServer(1)接收1號機(jī)的數(shù)據(jù),雙方兩條鏈路互不干擾。不過這種方案還是不太可取,因為加載控件需要占用內(nèi)存資源,每兩臺機(jī)之間其實只需一條鏈路就能正常通訊,現(xiàn)在又多了條鏈路,這對系統(tǒng)有限的資源是極大的浪費。

  方案三:三臺機(jī)有差互連

  先解釋一下什么叫有差互連。具體做法是:1號機(jī)只作為服務(wù)器監(jiān)聽2號和3號機(jī)的呼叫請求而不呼叫它們;2號機(jī)既是客戶機(jī)又是服務(wù)器:作為客戶機(jī)只呼叫1號機(jī),而作為服務(wù)器監(jiān)聽3號機(jī)的呼叫請求;3號機(jī)只作為客戶機(jī)對1號機(jī)和2號機(jī)進(jìn)行呼叫,而不具備服務(wù)器監(jiān)聽的功能。所以說這幾臺機(jī)的連接是有差的,這種連接方式不會在兩臺機(jī)之間建立兩條鏈路,因為網(wǎng)絡(luò)中任意兩臺機(jī)只有一臺可以呼叫對方或監(jiān)聽對方的呼叫請求,這樣無論如何都不會產(chǎn)生兩條通訊鏈路,節(jié)省了系統(tǒng)資源,又滿足了局域網(wǎng)中任意兩臺機(jī)互連的要求,由此看來這個方案是最優(yōu)方案。

  下面介紹方案三的實現(xiàn)過程。

  1號機(jī)

  1號機(jī)的窗體(Form)上放置兩個Winsock控件,一個名為TcpLsn,負(fù)責(zé)監(jiān)聽2號機(jī)和3號機(jī)的呼叫請求,另外一個為TcpConn,這是個控件數(shù)組,Index為2,即已經(jīng)加載了TcpConn(2),這個控件是為了和2號機(jī)建立連接。在初始化過程中(Form_Load)設(shè)置服務(wù)器的監(jiān)聽端口號(TcpLsn.LocalPort)并使其處于監(jiān)聽狀態(tài)(TcpLsn.Listen),并置與客戶機(jī)連接成功的標(biāo)志(TcpConnected數(shù)組,布爾型常量)為False。當(dāng)TcpLsn監(jiān)聽到某個客戶機(jī)的呼叫請求后(具體是哪個客戶機(jī)是根據(jù)客戶機(jī)IP地址判斷),在TcpLsn的ConnectionRequest事件中動態(tài)加載TcpConn控件并調(diào)用Accept方法接受客戶機(jī)的請求,與其建立連接(如果客戶機(jī)是2號機(jī),則無需再加載控件,因為在Form_Load中已經(jīng)加載過了)。要注意的是,TcpLsn只是用來監(jiān)聽客戶機(jī)的呼叫請求,而不是用來與客戶機(jī)建立連接的,TcpConn控件數(shù)組才是與客戶機(jī)建立連接的。當(dāng)某一客戶機(jī)斷開連接時,會觸發(fā)Tcpconn控件數(shù)組的Close事件,在這里可以根據(jù)客戶機(jī)的IP地址來調(diào)用Close方法關(guān)閉與其相連的Tcpconn控件,并動態(tài)卸載之。同樣TcpConn(2)不能卸載,因為其不是動態(tài)加載的。

  2號機(jī)

  2號機(jī)窗體(Form)上也放置兩個Winsock控件,一個名為TcpLsn,負(fù)責(zé)監(jiān)聽3號機(jī)的呼叫請求,另外一個為TcpConn,這是個控件數(shù)組,Index為1,即已經(jīng)加載了TcpConn(1),這個控件是為了與1號機(jī)建立連接。在初始化過程中(Form_Load)同樣要設(shè)置2號機(jī)作為服務(wù)器的監(jiān)聽端口號,然后使其處于監(jiān)聽狀態(tài),還要設(shè)置與其他幾個站點連接成功的標(biāo)志:TcpConnected(數(shù)組)。2號機(jī)作為服務(wù)器監(jiān)聽的過程同上,而呼叫1號機(jī)是通過VB6的定時器(Timer)實現(xiàn)的,定時器的作用是每隔一段時間(可自行設(shè)定間隔事件)觸發(fā)Timer事件,即執(zhí)行Timer事件中的代碼,利用這個原理就可以實現(xiàn)一運行此程序就自動進(jìn)行呼叫工作,首先將定時器間隔時間定為1000毫秒(定時器命名為TimConn,TimConn.Interval = 1000),然后在定時時間到事件中(TimConn_Timer)調(diào)用TcpConn的Connect方法呼叫1號機(jī),當(dāng)然要加一個判斷:當(dāng)TcpConnected(1)=False且TcpConn(1).State=sckClosed時才進(jìn)行呼叫。

  在客戶機(jī)調(diào)用了TcpConn方法后,其連接狀態(tài)是sckConnecting(正在連接服務(wù)器,值為6)。如果此時1號機(jī)在一段時間內(nèi)(連接服務(wù)器超時時間)沒有接受請求或者根本沒有開啟,那么就會觸發(fā)連接錯誤事件(TcpConn_Error),這時連接狀態(tài)是sckError(連接錯誤,值為9),就無法再進(jìn)行連接服務(wù)器的工作了,如果1號機(jī)此時打開,客戶機(jī)也不會再呼叫服務(wù)器了。要解決這個問題,可以在TcpConn的錯誤事件中(TcpConn_Error)加上一條語句:TcpConn(Index).Close即在錯誤事件中關(guān)閉當(dāng)前的連接,使當(dāng)前TcpConn控件狀態(tài)處于sckClosed,這樣在下一次的定時時間到事件中客戶機(jī)又能呼叫1號機(jī)了。呼叫1號機(jī)成功后,不要忘記在TcpConn的Connect事件中置連接1號機(jī)成功的標(biāo)志位。同樣要注意關(guān)閉事件中不能卸載TcpConn(1)。

  3號機(jī)

  3號機(jī)在所有站點中只呼叫1號機(jī)和2號機(jī)。所以只要一個Winsock控件數(shù)組即可,命名為TcpClient,Index=1。在程序初始化過程中,加載呼叫服務(wù)器的所有Winsock控件:Load TcpClient(2)
TcpClient(1)已經(jīng)放在窗體中了,故不必重復(fù)加載。還要設(shè)置連接成功的標(biāo)志位(TcpConnected數(shù)組為False),并設(shè)置定時器間隔時間。然后在定時時間到事件中調(diào)用TcpClient的Connect方法連接服務(wù)器,這與2號機(jī)作為客戶機(jī)呼叫服務(wù)器的過程類似,同樣要在TcpClient的連接錯誤事件中添加以下語句:TcpClient(Index).Close。要注意的是在服務(wù)器的斷開連接觸發(fā)的客戶機(jī)關(guān)閉事件中(TcpClient_Close)只需要置標(biāo)志位,而不能卸載TcpClient控件數(shù)組,因為其不是動態(tài)加載的。

  到此為止,基本上實現(xiàn)了運行此程序即進(jìn)行多機(jī)互連的功能。

  典型問題解析

  1.各個站點建立連接后關(guān)閉3號機(jī)的程序,在其它的站點就會彈出對象已加載的錯誤提示。出現(xiàn)這個錯誤的可能原因是Winsock控件已經(jīng)加載,而后又執(zhí)行了一次加載動作。不過實驗證明不是此Winsock控件被重復(fù)加載。在微軟公司的官方網(wǎng)站,VB6最新的Service Pack 5補(bǔ)?。⊿P5)的說明文檔中有這樣一條很重要的修正說明:重復(fù)加載或卸載Winsock控件會引起內(nèi)存泄露。這一修正是不是可以針對用Winsock控件實現(xiàn)網(wǎng)絡(luò)連接及通訊的程序呢?理論實踐證明了這一猜測的真實性。完SP5并成功安裝后,將程序原封不動運行一遍,“對象已加載”的錯誤窗口就再沒出現(xiàn)過,這個問題也就成功的解決了。

  2.由于設(shè)置了客戶機(jī)的本地端口號(LocalPort),導(dǎo)致必須先關(guān)閉服務(wù)器再關(guān)閉客戶機(jī)才能在下一次正常連接以及客戶機(jī)異常退出時(比如客戶機(jī)突然停電)導(dǎo)致下次無法正常連接。這是由于沒有釋放連接端口號造成的。這個錯誤的解決方法是不要設(shè)置客戶機(jī)的本地端口號;如果非得設(shè)置,那么可以利用動態(tài)改變服務(wù)器監(jiān)聽端口號和客戶機(jī)呼叫端口號的方法。具體做法是在服務(wù)器的Form_Load中改變監(jiān)聽端口號,在客戶機(jī)的Winsock控件錯誤事件中改變呼叫端口號,端口號只要用兩個就可以了(如1000和1001)。

相關(guān)頻道: eNews

您對本文或本站有任何意見,請在下方提交,謝謝!

投稿信箱:tougao@enet16.com