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

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

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

2004-02-23 eNet&Ciweek

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

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



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

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

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

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

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

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

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

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

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

  方案三:三臺機有差互連

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

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

  1號機

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

  2號機

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

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

  3號機

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

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

  典型問題解析

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

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

相關(guān)頻道: eNews

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

投稿信箱:tougao@enet16.com