利用Winsock控制項實現區域網路通訊
對於區域網路使用者中的編程愛好者來說,如果能自己編一個區域網路通訊程式,那麼這一切將是多麼美妙。可是,如果要從頭開始完全由自己來編寫一段用於通訊的程式,必須對相關的網路通訊協定及其他的一些較底層的技術有較深入的瞭解,這可不是一件容易的事。而現在有了Winsock控制項,一切就不同了,它已經替你封裝了所有煩瑣的技術細節,並提供了訪問TCP和UDP網路服務的方便途徑。你只需通過設定控制項的屬性並調用其方法就可輕易串連到一台遠端電腦中,並且還可以雙向交換資料,而這一切都不需你瞭解TCP的細節或調用低級的Winsock APIs。
Winsock控制項可以供Microsoft Acess、Visual Basic,Visual C++或Visual Foxpro的開發人員使用。本文以Visual Basic 6企業版為開發環境來向大家介紹一下Winsock控制項的初步應用。
Winsock控制項可以使用兩種協議:TCP協議和UDP協議,下面來分別介紹。
TCP協議即資料轉送協議,它允許建立和維護與遠端電腦的串連,使其彼此可以進行資料轉送。利用TCP協議通訊必須分別建立客戶應用程式和伺服器應用程式。
在建立客戶應用程式時,必須知道伺服器電腦名稱或其IP地址(存於RemoteHost屬性)、及伺服器電腦進行偵聽的連接埠(存於RemotePort屬性),然後調用Connect方法。
建立伺服器應用程式時,就應相應設定一個偵聽連接埠(LocalPort屬性)並調用listen方法。當客戶機需要串連時(connect),就會發生ConnectionRequest事件。為了完成串連,你可以在ConnectionRequest事件中調用Accept方法。建立串連後,任何一方電腦都可以發送、接收對方資料。如果你要發送資料,需調用SendData方法。當接收到資料時,會發生DataArrival事件,調用DataArrival事件中的GetData方法就可以獲得對方傳送的資料。
說了這麼多,大家可能還是不太瞭解,讓我用程式來詳細說明。
如果只有兩台電腦,那十分容易。假設甲機為客戶機,乙機為伺服器,且其IP為192.192.192.1,接收埠為1200(任意選一個未被使用的連接埠即可)。首先在甲機用戶端程式中加入一個Winsock控制項,起名為sckconnect,並設定其屬性:RemoteHost=“192.192.192.1”,(即甲機IP地址), RemotePort=1200(即甲機偵聽連接埠);再在乙機伺服器程式中假如一個名為sckserver(0)的Winsock控制項,其LocalPort=1200,
在乙機伺服器程式中Form_Load()加入
sckserver(0).bind sckserver(0).LocalPort '與本地連接埠綁定
sckserver(0).listern ' 偵聽
如果要傳輸資料,兩機必須先建立串連。建立串連的程式如下:
甲機客戶機要先請求串連
sckconnect.connect sckconnect.RemoteHost, sckconnect.RemotePort
此句執行時會觸發伺服器程式中的ConnectRequest事件,在此過程中決定是否建立串連,其代碼如下:
Private sub sckserver_connectionrequest(index as Integer,Byval requestid as long)
if sckserver.count=1 then
load sckserver(1)
sckserver(1).accept requestId
end if
end sub
串連建立好以後,甲機或乙機都可以應用SendData方法來傳送資料。例如,如果是甲機要傳送一個叫string的字串,只需在代碼中加入:
sckconnect.SendData string
甲機傳送資料後,會觸發乙機的DataArrival事件,在其過程中用GetData方法可以收到傳送的資料:
Private sub sckserver_DataArrival(Index as integer,Byval BytesTotal as long)
dim sdata as string
sckserver(1).GetData sdata,vbstring
end sub
最後別忘了在關閉程式前要先關閉Winsock控制項
privat sub form_unload(cancel as integer)
if sckconnect.state <> sckclosed then
sckconnect.close
end if
end sub
這隻是最簡單的情況,如果有多台電腦,那就稍微複雜一些,用戶端程式可以不做改動,而伺服器端程式需要略做改動:
Private sub sckserver_connectrequest(Index as Integer,Byval requestid as long)
dim sip as string
dim I as integer
sip=sckserver(0).RemoteHostIP '獲得登入者的IP地址
I=1
Do while I <=sckserver.ubound '檢查是否已經有該地址的記錄
If sckserver(I).RemoteHostIP=sip then '如有,不必載入新的控制項
Sckserver(I).Accept requestid
Exit sub
End if
I=I+1
Loop
Load sckserver(I) '否則,載入新的控制項
Scksrver(I).accept requestID
End sub
注意到:以上的資訊交談實際上都發生在客戶機與伺服器之間,如果要做成聊天室那樣,每個人的話都可以被別人“聽到”,那就要在伺服器端的DataArrival事件中,把接收到的客戶機傳來的資料,轉寄給所有客戶機即可。
其迴圈轉寄資訊的代碼如下:
For I=1 to sckserver.count
if sckserver(I).state <> sckclosed then
sckserver(I).SendData sdata
end if
next I