VB6 Socket编程
Winsock 控件對用戶來說是不可見的,它提供了訪問 TCP 和 UDP 網絡服務的方便途徑。Microsoft Access、Visual Basic、Visual C++ 或 Visual FoxPro 的開發人員都可使用它。為編寫客戶或服務器應用程序,不必了解 TCP 的細節或調用低級的 Winsock API。通過設置控件的屬性并調用其方法就可輕易連接到一臺遠程機器上去,并且還可雙向交換數據。
一、TCP 基礎?
數據傳輸協議允許創建和維護與遠程計算機的連接。連接兩臺計算機就可彼此進行數據傳輸。如果創建客戶應用程序,就必須知道服務器計算機名或者 IP 地址(RemoteHost 屬性),還要知道進行“偵聽”的端口(RemotePort 屬性),然后調用 Connect 方法。如果創建服務器應用程序,就應設置一個收聽端口(LocalPort 屬性)并調用 Listen 方法。當客戶計算機需要連接時就會發生 ConnectionRequest 事件。為了完成連接,可調用 ConnectionRequest 事件內的 Accept 方法。建立連接后,任何一方計算機都可以收發數據。為了發送數據,可調用 SendData 方法。當接收數據時會發生 DataArrival 事件。調用 DataArrival 事件內的 GetData 方法就可獲取數據。
二、UDP 基礎?
用戶數據文報協議 (UDP) 是一個無連接協議。跟 TCP 的操作不同,計算機并不建立連接。另外 UDP 應用程序可以是客戶機,也可以是服務器。為了傳輸數據,首先要設置客戶計算機的 LocalPort 屬性。然后,服務器計算機只需將 RemoteHost 設置為客戶計算機的 Internet 地址,并將 RemotePort 屬性設置為跟客戶計算機的 LocalPort 屬性相同的端口,并調用 SendData 方法來著手發送信息。于是,客戶計算機使用 DataArrival 事件內的 GetData 方法來獲取已發送的信息。?
屬性:
BytesReceived屬性,Index屬性,LocalHostName屬性,LocalIP屬性,LocalPort屬性,Object屬性,Name屬性,Parent屬性,Protocol屬性,RemoteHost屬性,RemoteHostIP屬性,RemotePort屬性,SocketHandle屬性,State屬性,Tag屬性。?
事件:
Close事件,Connet事件,ConnectionRequest事件,DataArrival事件,Error事件,SendComplete事件,SendProgress事件。?
方法:
Accept方法,Bind方法,Close方法(WinSock控件),Listen方法,PeekData方法,SendData方法,GetData方法(WinSock控件)。
三、Accept 方法?
僅適用于 TCP 服務器應用程序。在處理 ConnectionRequest 事件時用這個方法接受新連接。?
語法:object.Accept requestID?
object 所在處代表對象表達式,其值是WinSock控件的對象。?
數據類型:Long?
返回值:Void?
說明:在 ConnectionRequest 事件中使用 Accept 方法。ConnectionRequest 事件有一個對應的參數,即 RequestID 參數,該參數應該傳給 Accept 方法。請看下例:?
Private Sub Winsock1_ConnectionRequest?(ByVal requestID As Long)?
'測試 State 屬性,如果當前連接是打開的話,?
'則關閉連接。?
If Winsock1.State <> sckClosed Then Winsock1.Close?
'將 requestID 參數值傳遞給 Accept 方法。?
Winsock1.Accept requestID?
End Sub?
應該在新的控件示例(不是偵聽狀態下的示例)中使用 Accept 方法。
四、Bind 方法?
指定用于 TCP 連接的 LocalPort 和 LocalIP。如果有多協議適配卡,就用這個方法。?
語法:object.Bind LocalPort, LocalIP?
Bind 方法的語法包含下面部分
部分 描述
object 對象表達式,其值是WinSock控件的對象。
LocalPort 用來建立連接的端口。
LocalIP 用來建立連接的本地 Internet 地址。
說明: 在調用 Listen 方法之前必須調用 Bind 方法。
五、BytesReceived 屬性?
返回接收到的(當前在接收端緩沖區內的)數據的數量。使用 GetData 方法來獲取數據。?
在設計時是只讀的,而且是不可用的。?
語法:object.BytesReceived?
object 所在處代表一個對象表達式,其值是WinSock控件的對象。?
返回值:Long
六、Close 方法(Winsock 控件)?
對客戶機和服務器應用程序關閉 TCP 連接或偵聽套接字。?
語法:object.Close?
object 所在處代表對象表達式,其值是WinSock控件的對象。?
參數:None?
返回值:Void
七、Close 事件?
當遠程計算機關閉連接時出現。應用程序應正確使用 Close 方法關閉 TCP 連接。?
語法:object_Close( )?
object 所在處代表一個對象表達式,其值是WinSock控件的對象。?
參數:None
?
八、ConnectionRequest 事件?
當遠程計算機請求連接時出現。
僅適用于 TCP 服務器應用程序。在請求一個新連接時激活該事件。激活事件之后,RemoteHostIP 和 RemotePort 屬性存儲有關客戶的信息。
語法:object_ConnectionRequest (requestID As Long)
ConnectionRequest 的語法有包含下面部分:
部分 描述
object 對象表達式,其值是WinSock控件的對象。
RequestID 新連接請求標識。應把此參數傳遞給第二個控件示例上的 Accept 方法。
說明:服務器可決定是否接受連接。如果不接受新連接,則同級人員(客戶)將得到 Close 事件。(在一個新控件示例上)用 Accept 方法接受新連接。
九、Connect 事件 (Winsock 控件)?
當連接操作完成后產生。
語法:object.Connect()
object 所在處代表一個對象表達式,其值為一個 Winsock 控件。
說明:使用 Connect 事件確認連接是否已經成功。
十、Error 事件?
無論何時,只要后臺處理中出現錯誤(例如,連接失敗,或者在后臺收發數據失敗)事件就會出現。
語法:object_Error(number As Integer, Description As String, Scode As Long, Source As String, HelpFile as String, HelpContext As Long, CancelDisplay As Boolean)
Error 事件的語法包含下面部分:
部分 描述
object 對象表達式,其值是WinSock控件的對象。
number 定義錯誤代碼的整數。請參閱下述有關常數的“設置值”。
description 包含錯誤信息的字符串。
Scode 長 SCODE
Source 描述錯誤來源的字符串。
HelpFile 包含幫助文件名的字符串。
HelpContext Help 文件上下文。
CancelDisplay 指示是否取消顯示。缺省值為 False,以此顯示缺省的錯誤信息框。如果不想使用缺省的信息框,則將 CancelDisplay 設置成 True。
設置值
number 的設置值是:
常數 值 描述
sckOutOfMemory 7 內存不足
sckInvalidPropertyValue 380 屬性值無效。
sckGetNotSupported 394 屬性不可讀。
sckSetNotSupported 383 屬性是只讀的。
sckBadState 40006 所請求的事務或請求本身的錯誤協議或者錯誤連接狀態。
sckInvalidArg 40014 傳遞給函數的參數格式不確定,或者不在指定范圍內。
sckSuccess 40017 成功。
sckUnsupported 40018 不受支持的變量類型。
sckInvalidOp 40020 在當前狀態下的無效操作
sckOutOfRange 40021 參數越界。
sckWrongProtocol 40026 所請求的事務或請求本身的錯誤協議
sckOpCanceled 1004 取消操作。
sckInvalidArgument 10014 所請求的地址是廣播地址,但未設置標記
sckWouldBlock 10035 套接字不成塊,而指定操作將使之成塊。
sckInProgress 10036 制造塊的 Winsock 操作在進行之中。
sckAlreadyComplete 10037 完成操作。未進行制造塊的操作。
sckNotSocket 10038 描述符不是套接字。
sckMsgTooBig 10040 數據報太大,不適于緩沖區的要求,因而被截斷。
sckPortNotSupported 10043 不支持指定的端口。
sckAddressInUse 10048 地址在使用中。
SckAddressNotAvailable 10049 來自本地機器的不可用地址。
SckNetworkSubsystemFiled 10050 網絡子系統失敗。
sckNetworkUnreachable 10051 此時不能從主機到達網絡。
sckNetReset 10052 在設置SO_KEEPALIVE 時連接超時。
sckConnectAborted 11053 由于超時或者其它失敗而中止連接。
sckConnectionReset 10054 通過遠端重新設置連接。
SckNoBufferSpace 10055 沒有可用的緩沖空間。
SckAlreadyConnected 10056 已連接套接字。
SckNotConnected 10057 未連接套接字。
SckSocketShutdown 10058 已關閉套接字。
sckTimedout 10060 已關閉套接字。
sckConnectionRefused 10061 強行拒絕連接。
sckNotInitialized 10093 應首先調用 WinsockInit。
sckHostNotFound 11001 授權應答:未找到主機。
SckHostNotFoundTryAgain 11002 非授權應答:未找到主機。
SckNonRecoverableError 11003 不可恢復的錯誤。
SckNoData 11004 無效名,對所請求的類型無數據記錄。
十一、GetData 方法(Winsock 控件)?
獲取當前的數據塊并將其存儲在變體類型的變量中。
返回值:Void
語法:object.GetData data, [type,] [maxLen]
GetData 方法的語法包含下面部分:
部分 描述
object 對象表達式,其值是WinSock控件的對象。
data 在方法成功返回之后存儲獲取數據的地方。如果對請求的類型沒有足夠可用的數據,則將 data 設置成 Empty。
type 可選的。獲取的數據類型,如下例“設置值”所示。
maxLen 可選的。在接收到字節數組或字符串時所需大小。如果對字節數組或字符串、參數丟失、則將獲取所有可用數據。如果提供的數據類型不是字節數組或字符串,則忽略這個參數。
設置值
type 的設置值是:
描述 常數 描述 常數
Byte vbByte Integer vbInteger
Long vbLong Single vbSingle
Double vbDouble Currency vbCurrency
Date vbDate Boolean vbBoolean
SCODE vbError String vbString
Byte Array vbArray + vbByte
說明:通常總是將 GetData 方法與 DataArrival 事件并用,而 DataArrival 事件包含 totalBytes 參數。如果指定一個比 totalBytes 參數小的 maxlen,則將得到警告 10040,以此指出剩余的字節將丟失。
十二、Listen 方法?
創建套接字并將其設置為偵聽模式。該方法僅適用于 TCP 連接。
語法:object.Listen
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
參數:None
返回值:Void
說明:當有新連接時就會出現 ConnectionRequest 事件。處理 ConnectionRequest 事件時,應用程序應該(在一個新的控件示例上)用 Accept 方法接受連接。
十三、LocalHostName 屬性?
返回本地機器名。在設計時是只讀的,而且是不可用的。
語法:object.LocalHostName
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
返回值:String
十四、LocalIP 屬性?
返回本地機器的 IP 地址,格式是 IP 地址加點字符串 (xxx.xxx.xxx.xxx)。在設計時是只讀的,而且是不可用的。
語法:object.LocalIP
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
數據類型:String
十五、LocalPort 屬性?
返回或者設置所用到的本地端口。在設計時是可讀/寫的,而且是可用的。
對客戶來說,該屬性指定發送數據的本地端口。如果應用程序不需要特定端口,則指定 0 為端口號。在這種情況下,控件將選擇一個隨機端口。在建立起連接之后,這就是用于 TCP 連接的本地端口。
對于服務器來說,這是用于偵聽的本地端口。如果指定的是端口 0,就使用一個隨機端口。在調用了 Listen 方法后,屬性就包含了已選定的實際端口。
語法:object.LocalPort = long
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
數據類型:Long
說明:在計算機之間常用端口 0 來動態地建立連接。例如,一個客戶希望服務器給他“回電話”,它就可用端口 0 獲得新的(隨機)端口號,然后將該端口號交給遠程計算機,從而達到目的。
十六、Name 屬性?
返回在代碼中用于標識窗體、控件、或數據訪問對象的名字。在運行時是只讀的。
返回或設置字體對象的名字。
語法:object.Name
object 所在處代表一個對象表達式,其值是WinSock控件的對象。如果 object 被刪去,則與活動窗體模塊相聯系的窗體被認為是 object。
說明:新對象的缺省名字由對象類型加上一個唯一的整數組成。例如,第一個新的 Form 對象是 Form1, 一個新的 MDIForm 對象是 MDIForm1,以及在窗體上創建的第三個 TextBox 控件是 Text3。
一個對象的 Name 屬性必須以一個字母開始并且最長可達 40 個字符。它可以包括數字和帶下劃線 (_) 的字符,但不能包括標點符號或空格。窗體不能具有與別的公共對象相同的名字,例如 Clipboard、Screen 或 App。雖然 Name 屬性設置可以是一個關鍵字、屬性名字、或別的對象的名字,但這會在你的代碼中產生沖突。能夠在運行時與 Dim 語句一起使用一個窗體的 Name 屬性,以此創建該窗體的其它實例。在設計時不能有兩個窗體有相同的名字。能夠通過設置 Name 屬性為相同的值來創建相同類型的控件數組。例如,當將群組中的所有選項按鈕的名字設置為 MyOpt 時,Visual Basic 將為每個控件的 Index 屬性分配一個唯一的值以便使數組中的控件相互區分。不同類型的兩個控件不能共享相同的名字。
注意 雖然 Visual Basic 經常將 Name 屬性設置作為 Caption、LinkTopic 和 Text 屬性的缺省值使用,但是這些屬性中一個的改變對別的屬性并沒有影響。
十七、Parent 屬性?
返回包含控件、或其它對象或者集合的窗體、對象、或集合。
語法:object.Parent
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
說明:使用 Parent 屬性可訪問一個對象的父親的屬性、方法、或控件。例如:
MyButton.Parent.MousePointer = 4
Parent 屬性在應用程序中是很有用的,其中可將對象作為參數來傳遞。例如,可以傳遞一個控件變量給模塊中的一個一般的過程,并使用 Parent 屬性訪問其父窗體。 在 Parent 屬性和 MDIChild 屬性之間沒有任何聯系。盡管如此,但在一個 MDIForm 對象和任何已經將其 MDIChild 屬性設為 True 的 Form 對象之間仍有父-子關系。
十八、PeekData 方法?
PeekData 不從輸入隊列刪除數據,除了這一點之外,方法與 GetData 相似。該方法僅適用于 TCP 連接。
語法: object.PeekData data, [type,] [maxLen]
PeekData 方法的語法包含下面部分:
部分?描述
object 對象表達式,其值是WinSock控件的對象。
data 在方法成功地返回之后存儲獲取的數據。如果對于沒有足夠的適于所請求的類型來說沒有足夠可用的數據,那么 data 將被設置為 Empty。
type 可選的。所獲取的數據類型,如同“設置值”中所述。缺省值為:vbArray + vbByte。
maxLen 可選的。在收到字節數組或字符串時,長度指定了所需要的大小。如果對字節數組或字符串的參數丟失,則將獲取所有可用的數據。如果提供的數據類型不是字節數組和字符串的話,則忽略該參數。
設置值
type 的設置值是:?
描述 常數
Byte vbByte
Integer vbInteger
Long vbLong
Single vbSingle
Double vbDouble
Currency vbCurrency
Date vbDate
Boolean vbBoolean
SCODE vbError
String vbString
Byte Array vbArray + vbByte
返回值:Void
說明:如果所指定的類型為 vbString,則在返回到用戶之前,字符串數據將轉化成 UNICODE。
十九、Protocol 屬性(Winsock 控件)?
返回或設置 Winsock 控件所使用的協議— 或者是 TCP,或者是 UDP。
語法:object.Protocol [=protocol]
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
設置值
protocol 的設置值是:
常數 值 描述
sckTCPProtocol 0 缺省的。TCP 協議。
sckUDPProtocol 1 UDP協議。
返回值:Void
說明:在能夠重新設置屬性之前必須(用 Close 方法)關閉控件。
二十、RemoteHost 屬性(ActiveX控件)?
返回或設置控件發送或接收數據的遠程計算機。可以提供直接名如http://www.baidu.com/,或提供IP地址如“202.99.14.22”。
語法: object.RemoteHost = string
RemoteHost屬性語法有以下幾部分:
部分 描述
Object 對象表達式,其值是WinSock控件的對象。
String 遠程計算機的名字或IP地址。
數據類型:String
說明:當指定了該屬性時,URL屬性跟著更新以便反映新值。并且,如果URL的協議部分更新了,RemoteHost屬性也跟著更新以便反映新值。使用OpenURL和Execute方法會改變該屬性的值。
二十一、RemoteHostIP 屬性?
返回遠程機器的 IP 地址。
對于客戶應用程序來說,已經用 Connect 方法建立連接后,屬性就包含了遠程機器的 IP 字符串。對于服務器應用程序來說,在請求連接(ConnectionRequest 事件)之后,屬性包含遠程計算機的 IP 字符串,該字符串啟動了連接。當使用 UDP 協議時,在 DataArrival 事件出現之后,屬性包含了發送 UDP 數據的計算機的 IP 地址。
語法:object.RemoteHostIP
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
數據類型:String
二十二、RemotePort 屬性(ActiveX控件)?
設置或返回要連接的遠程端口號。
語法:object.RemotePort = port
RemotePort屬性語法有以下幾部分:
部分?描述
object 對象表達式,其值是WinSock控件的對象。
Port 要連接的端口號。缺省值是80。
數據類型:Long
說明:當設置Protocol屬性時,RemotePort屬性也自動為每種協議設置相應的缺省端口。
下表列出了缺省的端口:
端口號 描述
80 HTTP,通常用于World Wide Web連接。
21 FTP
二十三、SendComplete 事件?
在完成一個發送操作時出現。
語法:object_SendComplete
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
參數:None
二十四、SendData 方法?
將數據發送給遠程計算機。
返回值:Void
語法:object.SendData data
SendData 方法的語法有下面這些部分:
部分 描述
Object 對象表達式,其值是WinSock控件的對象。
data 要發送的數據。對于二進制數據應使用字節數組。
說明 當傳進 UNICODE 字符串并在網絡上發送出去之前,將轉化成 ANSI 字符串。
二十五、SendProgress 事件?
在發送數據期間出現。
語法:object_SendProgress (bytesSent As Long, bytesRemaining As Long)
SendProgress 事件的語法包含下面部分:
部分 描述
object 對象表達式,其值是WinSock控件的對象。
bytesSent 從上次激活事件以來已發送的字節數。
bytesRemaining 在發送緩沖區等待發送時的字節數。
二十六、SocketHandle 屬性?
返回一個與套接字句柄對應的值,控件用套接字句柄同 Winsock 層通信。在設計時是只讀的,而且是不可用的。
語法:object.SocketHandle
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
數據類型Long
說明:這個屬性是為了傳遞到 Winsock APIs 而設計的。
二十七、State 屬性(Winsock 控件)?
返回控件的狀態,用枚舉類型來表示。在設計時是只讀的,而且是不可用的。
語法:object.State
object 所在處代表一個對象表達式,其值是WinSock控件的對象。
數據類型:Integer
設置值
State 屬性的設置值是:
常數 值 描述
SckClosed 0 缺省的。關閉
SckOpen 1 打開
SckListening 2 偵聽
SckConnectionPending 3 連接掛起
SckResolvingHost 4 識別主機
SckHostResolved 5 已識別主機
SckConnecting 6 正在連接
SckConnected 7 已連接
SckClosing 8 同級人員正在關閉連接
SckError 9 錯誤?
| 先在一臺計算機上運行服務器程序,此時窗口上只有一個“退出”按鈕。 再在另一臺計算機上運行客戶機程序,在“連接”按鈕右邊的文本框中輸入服務器的主機名后單擊“連接”按鈕。如果連接成功,則服務器和客戶機程序窗口都會出 現兩個文本框。這時,兩端都可以在上面的文本框中輸入文字,這些文字會立即在下面的文本框中出現。 服務器程序使用的控件如下: (1)Command1:退出按鈕; (2)textsend:發送數據文本框; (3)Winsockserver: 服務器Winsock; (4)textget :接收數據文本框。 服務器程序的界面如圖所示。 服務器程序的源代碼如下: Private Sub Command1_Click() End End Sub Private Sub Form_Load() textsend.Visible = False textget.Visible = False Winsockserver.LocalPort = 1001 Winsockserver.Listen End Sub Private Sub textsend_Change() Winsockserver.SendData textsend.Text End Sub Private Sub Winsockserver_Close() Winsockserver.Close End End Sub Private Sub Winsockserver_ConnectionRequest(ByVal requestID As Long) textsend.Visible = True textget.Visible = True If Winsockserver.State <> sckClosed Then Winsockserver.Close Winsockserver.Accept requestID End Sub Private Sub Winsockserver_DataArrival(ByVal bytesTotal As Long) Dim tmpstr As String Winsockserver.GetData tmpstr textget.Text = tmpstr End Sub 客戶機程序使用的控件如下: (1)Command1:退出按鈕; (2)Command2:連接按鈕; (3)Winsockclient:客戶Winsock; (4)Text1:主機名文本框; (5)Textsend:發送數據文本框; (6)Textget:接收數據文本框; 客戶機程序的源代碼如下: Private Sub Command1_Click() End End Sub Private Sub Command2_Click() Winsockclient.Connect End Sub Private Sub Form_Load() textsend.Visible = False textget.Visible = False Winsockclient.RemotePort = 1001 Winsockclient.RemoteHost = "sccdsz" End Sub Private Sub Text1_Change() Winsockclient.RemoteHost = Text1.Text End Sub Private Sub textsend_Change() Winsockclient.SendData textsend.Text End Sub Private Sub Winsockclient_Close() Winsockclient.Close End End Sub Private Sub winsockclient_Connect() textsend.Visible = True textget.Visible = True Command2.Visible = False End Sub Private Sub winsockclient_DataArrival(ByVal bytesTotal As Long) Dim tmpstr As String Winsockclient.GetData tmpstr textget.Text = tmpstr End Sub |
a
http://blog.csdn.net/snlei/article/details/10977561
總結
以上是生活随笔為你收集整理的VB6 Socket编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数值分析复习(六)——常微分方程数值解法
- 下一篇: 光立方制作