VB6.0中WinSock控件屬性和方法詳解

  WinSock控件能夠通過UDP協議(用戶數據報協議)或TCP協議(數據傳輸協議)連接到遠程的機器並進行數據交換。這兩種協議都能用來創建客戶端和服務端應用程序。就像定時器控件一樣,WinSock控件運行時沒有一個可視的界面。

一、WinSock簡介
       Socket(套接字)最初是由加利福尼亞大學Berkeley(伯克利)分校爲UNIX操作系統開發的網絡通信接口,隨着UNIX的廣泛使 用,Socket成爲當前最流行的網絡通信應用程序接口之一。20世紀90年代初,由Sun Microsystems,JSB,FTP software,Microdyne和Microsoft等幾家公司共同定製了一套標準,即Windows Socket規範,簡稱WinSock。
VB編寫網絡程序主要有兩種方式:1.winsock控件 2.winsockAPI

二、可能的用途

  ·創建客戶端應用程序,它能在信息到達中央服務器之前把用戶的信息收集起來。
·創建服務端應用程序,它能作爲來自多個用戶的數據一個集中處理點。
·創建“聊天”程序。

三、WinSock控件的使用
1.WinSock控件的主要屬性

LocalHostName屬性 本地機器名

LocalIP屬性 本地機器IP地址

LocalPort屬性 本地機器通信程序的端口(0<端口<65536)

RemoteHost屬性 遠程機器名

RemotePort屬性 遠程機器的通信程序端口
Protocol屬性 
通過Protocol屬性可以設置WinSock控件連接遠程計算機使用的協議。可選的協議是TCP和UDP對應的VB的常量分別是 sckTCPProtocol和sckUDPProtocol,Winsock控件默認協議是TCP。注意:雖然可以在運行時設置協議,但必須在連接未建 立或斷開連接後。
SocketHandle屬性 返回當前socket連接的句柄,這是隻讀屬性。
RemoteHostIP屬性
屬性返回遠程計算機的IP地址。在客戶端,當使用了控件的Connect方法後,遠程計算機的IP地址就賦給了RemoteHostIP屬性,而在服務器 端,當ConnectRequest事件後,遠程計算機(客戶端)的IP地址就賦給了這個屬性。如果使用的是UDP協議那麼當DataArrival事件 後,發送UDP報文的計算機的IP才賦給了這個屬性。
ByteReceived屬性 返回當前接收緩衝區中的字節數
State屬性 返回WinSock控件當前的狀態
常數

描述 
    sckClosed                   0      缺省值,關閉。 
    SckOpen                     1      打開。 
    SckListening                2      偵聽 
    sckConnectionPending        3      連接掛起 
    sckResolvingHost            4      識別主機。 
    sckHostResolved             5      已識別主機 
    sckConnecting               6      正在連接。 
    sckConnected                7      已連接。 
    sckClosing                  8      同級人員正在關閉連接。 
    sckError                    9   錯誤 

2.WinSock主要方法

Listen方法 方法用於服務器程序,等待客戶訪問。格式:Winsock對象.listen

Connect方法 用於向遠程主機發出連接請求。格式:Winsock對象.connect [遠程主機IP,遠程端口]

Accept方法 用於接受一個連接請求。格式:Winsock對象.accept Request ID

Senddata方法 用於發送數據。格式:Winsock對象.senddata 數據

Getdata方法 用來取得接收到的數據。格式:Winsock對象.getdata 變量 [,數據類型 [,最大長度]]

Close方法 關閉當前連接。格式:Winsock對象.close
Bind方法 用Bind方法可以把一個端口號固定爲本控件使用,使得別的應用程序不能再使用這個端口。
Listen方法Listen方法只在使用TCP協議時有用。它將應用程序置於監聽檢測狀態。
Connect方法 當本地計算機希望和遠程計算機建立連接時,就可以調用Connect方法。Connect方法調用的規範爲:Connect RemoteHost,RemotePort
Accept方法 當服務器接收到客戶端的連接請求後,服務器有權決定是否接受客戶端的請求。
SendData方法當連接建立後,要發送數據就可以調用SendData方法,該方法只有一個參數,就是要發送的數據。
GetData方法 當本地計算機接收到遠程計算機的數據時,數據存放在緩衝區 中,要從緩衝區中取出數據,可以使用GetData方法。GetData方法調用規範如下:GetData data,[type,][maxLen]它從緩衝區中取得最長爲maxLen的數據,並以type類型存放在data中,GetData取得數據後,就 把相應的緩衝區清空。
PeekData方法 和GetData方法類似,但PeekData在取得數據後並不把緩衝區清空。

3.Winsock控件主要事件
Close事件 遠程機器關閉連接時觸發

Connect事件 連接建立好,可以進行通信時觸發(客戶端)
ConnectRequest事件 當本地計算機接收到遠程計算機發送的連接請求時,控件的ConnectRequest事件將會被觸發。
SendProgress事件 當一端的計算機正在向另一端的計算機發送數據時,SendProgress事件將被觸發。SendProgress事件記錄了當前狀態下已發送的字節數和剩餘字節數。
SendComplete事件 當所有數據發送完成時,被觸發。
DataArrival事件 當建立連接後,接受到了新數據就會觸發這個事件。注意:如果在接受到新數據前,緩衝區中非空,就不會觸發這個事件。
Error事件 當在工作中發生任何錯誤都會觸發這個事件。

四、Winsock控件詳解

  協議的選擇

  當我們使用WinSock控件時,首先要確定的是使用TCP還是UDP協議。它們之間主要的區別在於連接狀態:

  TCP協議控件是一個基於連接的協議,就像電話機一樣,用戶必須在通話之前建立連接;

  UDP是一個無連接的協議,兩臺計算機之間的事務處理就像傳紙條一樣:一臺計算機向另一臺計算機發送消息,但是它們之間並沒有一個明確的連接路徑。另外,發送的單個信息量的大小取決於網絡。

  通常,你要創建的應用程序的類別就決定了你要選擇的協議。以下是幾個能夠幫助你選擇合適的協議的問題:

  當發送或接收數據時,該應用程序需要從服務端或客戶端獲得認證嗎?如果要的話,那麼TCP協議就正好需要在發送或接受數據前建立明確的連接。

  要發送的數據量大嗎?(就像圖片、聲音文件之類)一旦建立了連接,TCP協議就會保持連接並保證數據的完整性。但是,這種連接會佔用的更多的處理器資源,成本也會更高一些。

  數據是陸續傳輸的,還是一次全部傳完呢?比如,如果你要創建的應用程序在某些任務完成時會告知具體的計算機,那麼選擇UDP協議會更合適一些。UDP協議也更適合於發送小量數據。

  協議的配置

配置你的應用程序所用到的協議:在設計階段,單擊工具窗口裏的協議,選擇

  sckTCPProtocol或sckUDPProtocol。你也可以在代碼裏配置協議,就像下面這樣:

Winsock1.Protocol=sckTCPProtocol

  確定你的計算機名

  要連接到遠程的計算機,你必須知道它的IP地址或別名。IP地址是一串用句點分隔的3位數字。通常,計算機的別名更容易讓人記住。
按下面的步驟可以找到你的計算機名:

  ·在“任務欄”裏單擊“開始”
·在“設置”選項裏單擊“控制面板”;
·雙擊“網絡”圖標;
·單擊“網絡標識”
在“計算機名”中顯示的就是你的計算機名。一旦你找到你的計算名,它就可以作爲遠程主機的屬性來用了。

  TCP連接入門

當用TCP控件創建應用程序的時候,必須首先明確你的程序是作爲服務端還是客戶端。創建服務端程序就意味着你的程序能夠在指定的端口進行“監聽”,而客戶端則能夠提出請求,服務端能夠接受請求並實現連接。一旦連接建立起來,客戶端和服務端就能夠自由地進行通信。

創建服務端程序

  下面是創建一個簡單服務端程序的步驟:

  ·創建一個標準EXE工程;
·把默認窗體(Default form)的名字改爲frmServer;
·把form的標題(caption)改爲TCP Server;
·把Winsock控件拉到窗體中,並命名爲tcpServer;
在窗體中添加2個文本框,分別命名爲txtSendData和txtOutput


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
'在窗體中加入下列代碼;
Private Sub Form_Load() ' Set the LocalPort property to an integer.
' Then invoke the Listen method.
tcpServer.LocalPort = 1001 tcpServer.Listen frmClient.Show ' Show the client form.
End Sub Private Sub tcpServer_ConnectionRequest _ (ByVal requestID As Long) ' Check if the control's State is closed. If not,
' close the connection before accepting the new
' connection.
If tcpServer.State <> sckClosed Then _ tcpServer.Close ' Accept the request with the requestID
' parameter.
tcpServer.Accept requestID End Sub   Private Sub txtSendData_Change() ' The TextBox control named txtSendData
' contains the data to be sent. Whenever the user
' types into the textbox, the string is sent
' using the SendData method.
tcpServer.SendData txtSendData.Text End Sub   Private Sub tcpServer_DataArrival _ (ByVal bytesTotal As Long) ' Declare a variable for the incoming data.
' Invoke the GetData method and set the Text
' property of a TextBox named txtOutput to
' the data.
Dim strData As String tcpServer.GetData strData txtOutput.Text = strData End Sub

  上面就是創建一個簡單的服務端應用程序的過程。然而,要完成整個過程,你還得創建一個客戶端程序。

  創建TCP客戶端程序

  ·在工程中添加一個新的窗體(form),並命名爲frmClient;
·將窗體的標題(caption)改爲TCP Client;
·添加一個Windsock控件到窗體中,命名爲tcpCllient;
·添加2個文本框控件到frmClient窗體,分別命名爲txtSend和txtOutput;
·添加一個按鈕控件(CommandButton)到窗體,命名爲cmdConnecti;
·將按鈕控件標題(caption)改爲Connect;

  在窗體中添加下面代碼:

  注:確保將遠程主機屬性(RemoteHost property)改爲你的計算機別名。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Private Sub Form_Load()
' The name of the Winsock control is tcpClient.
' Note: to specify a remote host, you can use
' either the IP address (ex: "121.111.1.1") or
' the computer's "friendly" name, as shown here.
tcpClient.RemoteHost = "RemoteComputerName" tcpClient.RemotePort = 1001 End Sub   Private Sub cmdConnect_Click() ' Invoke the Connect method to initiate a
' connection.
tcpClient.Connect End Sub   Private Sub txtSendData_Change() tcpClient.SendData txtSend.Text End Sub   Private Sub tcpClient_DataArrival _ (ByVal bytesTotal As Long) Dim strData As String tcpClient.GetData strData txtOutput.Text = strData End Sub

  以上代碼就能創建一個簡單的c/s應用程序。要試着讓兩者建立連接,可以運行工程,單擊Connect。在任意一個txtSendData文本框中輸入文本,同樣的文本信息就會出現在另一個窗體的txtOutput文本框中出現。

  接受多個連接請求

  上面介紹的服務端程序智能接受一個連接請求。但是,通過創建一組控件,並使用同樣的控件來接受多個連接請求也是可能的。在這種情況下,你不需要關閉連接,只要創建新的控件實例(通過配置它的索引屬性),調用新的實例中的接受方法。

  下面的代碼中,假定在一個叫sckServer的窗體中有一個Winsock控件,它的索引屬性設置爲0。這樣這個控件就是控件數組的一部分。 在聲明段中,生命一個模塊級變量intMax。在窗體的載入事件中,intMax被設置爲0,數組中第一個控件的本地端口屬性被設置爲1001。

  監聽方法在控件中被調用,它被作爲“監聽控件”。每個連接請求到來時,代碼會測試看它的索引(Index)是否爲0(監聽控件的值),如果是0,監聽控件中intMax值增1,並用這個值創建新的控件實例。新的控件實例被用來接受連接請求。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Private intMax As Long
 
Private Sub Form_Load()
intMax = 0
sckServer(0).LocalPort = 1001
sckServer(0).Listen
End Sub
 
Private Sub sckServer_ConnectionRequest _
(Index As Integer, ByVal requestID As Long)
If Index = 0 Then
intMax = intMax + 1
Load sckServer(intMax)
sckServer(intMax).LocalPort = 0
sckServer(intMax).Accept requestID
Load txtData(intMax)
End If
End Sub

  UDP連接入門

創建一個UDP應用程序比創建TCP程序更簡單,因爲UDP協議不需要一個確定的連接。在上面的TCP應用程序中,其中一個Winsock控件必須明確的被設置爲“監聽”,而另一個必須用連接方法發起連接。

  相反,UDP協議不需要明確的連接。要在2個控件之間傳送數據,(連接的雙方)必須完成三個步驟:

  ·確定遠程主機屬性爲對方的計算機名;
·確定遠程主機屬性爲第二個控件的本地端口屬性;

  調用約定方法指定要被使用的本地端口。(下面將詳細討論該方法)

  ·創建一個的UDP連接端
·創建一個標準EXE工程;
·將默認窗體命名爲frmPeerA;
·在窗體中添加一個Winsock控件,命名爲udpPeerA;
·在屬性(Properties)頁,單擊協議(Protocol),改爲UDPProtocol;
·添加2個文本框控件窗體中,分別命名爲txtSend和txtOutput;

  在窗體中添加下面代碼:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Private Sub Form_Load()
' The control's name is udpPeerA
With udpPeerA ' IMPORTANT: be sure to change the RemoteHost
' value to the name of your computer.
.RemoteHost= "PeerB" .RemotePort = 1001 ' Port to connect to.
.Bind 1002 ' Bind to the local port.
End With frmPeerB.Show ' Show the second form.
End Sub   Private Sub txtSend_Change() ' Send text as soon as it's typed.
udpPeerA.SendData txtSend.Text End Sub   Private Sub udpPeerA_DataArrival _ (ByVal bytesTotal As Long) Dim strData As String udpPeerA.GetData strData txtOutput.Text = strData End Sub

  創建第二個UDP連接端

  ·添加標準窗體到工程中;
·將窗體名改爲frmPeerB;
·將窗體標題改爲Peer B;
·在窗體中添加一個Windsock控件並命名爲udpPeerB;
·在屬性頁中單擊Protocol,改爲UDPProtocol;
·添加2個文本框到窗體中,分別命名爲txtSend和txtOutput;

  在窗體中添加下面代碼:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Private Sub Form_Load()
' The control's name is udpPeerB.
With udpPeerB ' IMPORTANT: be sure to change the RemoteHost
' value to the name of your computer.
.RemoteHost= "PeerA" .RemotePort = 1002 ' Port to connect to.
.Bind 1001 ' Bind to the local port.
End With End Sub   Private Sub txtSend_Change() ' Send text as soon as it's typed.
udpPeerB.SendData txtSend.Text End Sub   Private Sub udpPeerB_DataArrival _ (ByVal bytesTotal As Long) Dim strData As String udpPeerB.GetData strData txtOutput.Text = strData End Sub

  關於約定方法

  上面代碼中所涉及的,在創建UDP應用程序時必須調用約定方法。這個約定的方法保留了控件用到的本地端口。例如,當你綁定控件到端口1001時,其他的應用程序都不能用該端口監聽。當你希望阻止其他的應用程序使用某端口的時候,這個就很有用。

  這個約定方法也引起了爭議。如果機器裏有多個網絡適配器,本地IP允許你指定用哪個適配器。如果你忽略了這個爭議性問題,控件就會使用計算機控制面板設置中,在網絡控制面板對話框裏列出的第一個網絡適配器。

  在使用UDP協議時,你可以自由的切換遠程主機和遠程端口屬性,同時保留本地端口範圍。但是在使用UDP協議時,你必須在改變遠程主機和遠程端口屬性時關閉連接。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章