|
最近剛接觸VB,學(xué)習(xí)了用Winsock創(chuàng)建聊天應(yīng)用程序。下面的實(shí)例分別用 TCP協(xié)議和UDP協(xié)議實(shí)現(xiàn)通訊。 1.選擇通訊協(xié)議的標(biāo)準(zhǔn) 在使用WinSock控件時(shí),可以使用的協(xié)議包括TCP和UDP。兩種協(xié)議之 間的重要區(qū)別在于它們的連接狀態(tài):a).TCP協(xié)議控件是基于連接的協(xié)議,可以 將它同電話系統(tǒng)相比。在開始數(shù)據(jù)傳輸之前,用戶必須先建立連接。b).UDP協(xié) 議是一種無連接協(xié)議,兩臺計(jì)算機(jī)之間的傳輸類似于傳遞郵件:消息從一臺計(jì)算 機(jī)發(fā)送到另一臺計(jì)算機(jī),但是兩者之間沒有明確的連接。 2.Winsock控件使用TCP協(xié)議 如果應(yīng)用程序要使用TCP協(xié)議,那么首先必須決定應(yīng)用程序是服務(wù)器還是 客戶端。如果要創(chuàng)建一個(gè)服務(wù)器端,那么應(yīng)用程序需要“監(jiān)聽”指定的端口。當(dāng)客 戶端提出連接請求時(shí),服務(wù)器端能夠接受請求并建立連接。在連接建立之后,客 戶端與服務(wù)器端可以自由地互相通訊。 2.1TCP服務(wù)器端 窗體設(shè)計(jì): ![]() 為窗體添加如下的代碼: Private Sub Form_Load() '設(shè)置本地端口號為6000 Winsock1.LocalPort = 6000 '打開監(jiān)聽 Winsock1.Listen End Sub Private Sub Winsock1_ConnectionRequest(ByValRequestlD As Long) Dim myStr As String 如果當(dāng)前狀態(tài)處于連接狀態(tài),則先關(guān)閉連接,再接收新的請求 If Winsock1.State <> sckClosed Then myStr = MsgBox("客戶請求建立連接,是否允許?",vbOKCancel) If myStr = vbOK Then '關(guān)閉連接 Winsock1.Close '接收客戶請求,建立連接 Winsock1.Accept RequestlD Winsock1.SendData '接收 MsgBox "與客戶建立了新連接" End If End If End Sub Private Sub Winsock 1_DataArrival(ByVallbytes Total As Long) Dim myStr As String '調(diào)用GetData方法接收數(shù)據(jù) Winsock1.GetData myStr Text2.Text = myStr End Sub Private Sub Winsock1_Close() Winsock1.Close Winsock1.Listen MsgBox "與客戶斷開連接" End Sub Private Sub Text1_Change) '當(dāng)服務(wù)器端的文本框中的內(nèi)容發(fā)生變化時(shí),使用SendData方法發(fā)送信息 Winsock1.SendData Text1.Text End Sub 2.2TCP客戶端 窗體設(shè)計(jì): ![]() 為窗體添加如下代碼: Private Sub Form_Load() Text1 = "192.168.1.22" Text2 = 6000 End Sub Private Sub Command1_Click() If Winsock1.State = sckClosed Then '設(shè)置服務(wù)器的IP地址 Winsock1.RemoteHost = Trim( Text1.Text) '設(shè)置服務(wù)器的端口號 Winsock1.RemotePort = Trim( Text2.Text) '發(fā)出連接請求 Winsock1.Connect End If End Sub Private Sub Winsock 1_DataArrival(ByValbytes Total As Long) Dim myStr As String '調(diào)用GetData方法接收數(shù)據(jù) Winsock1.GetData myStr Text4.Text = myStr Option1.Value = True End Sub Private Sub Winsock1_Close() Winsock1.Close Option2.Value = True End Sub Private Sub Text3_Change() '當(dāng)xtSend控件的內(nèi)容發(fā)生變化時(shí),調(diào)用SendData將信息傳送給主機(jī) Winsock1.SendData Text3.Text End Sub 2.3運(yùn)行方法 1)同時(shí)運(yùn)行服務(wù)器端程序和客戶端程序,得到兩個(gè)示意圖(略) 2)在客戶端程序的界面中單擊“連接”按鈕,此時(shí),服務(wù)器端程序顯示“客戶請 求建立連接,是否允許?” 3)單擊“確定”,客戶端的連接狀態(tài)會變成“連接”狀態(tài),此時(shí),兩端已建立起 連接。 4)在服務(wù)器端的“發(fā)送的消息”文本框中輸入信息,在客戶端的“接收到的消息” 文本框中會看到同樣的消息,反之亦然。 3.Winsock控件使用TCP協(xié)議 創(chuàng)建UDP應(yīng)用程序時(shí)必須調(diào)用Bind方法,Bind方法的作用是為控件“保留” 一個(gè)本地端口。在使用UDP協(xié)議的時(shí)候,可以任意地改變RemoteHost和 RemotePort屬性,同時(shí)始終保持綁定在同一個(gè)LocalPort上。TCP協(xié)議與此不 同,在改變RemoteHost和RemotePort屬性之前,必須先關(guān)閉連接。因?yàn)閮?nbsp; 臺計(jì)算機(jī)的地位可以看成“平等的”,這種應(yīng)用程序也被稱為點(diǎn)到點(diǎn)的。服務(wù)器端 和客戶端窗體布局相同,可把兩端的名稱分別設(shè)為“UDP通信A”“UDP通信B”, 以示區(qū)分,兩端的代碼也相同。 ![]() Private Sub Command1_Click() With Winsock1 '設(shè)置遠(yuǎn)程主機(jī)名 .RemoteHost = Trim(Text1.Text) '設(shè)置遠(yuǎn)程端口號 .RemotePort = Trim(Text2.Text) '綁定本地端口號 .Bind Trim(Text3.Text) End With End Sub Private Sub Text4_Change) '數(shù)據(jù)發(fā)生變化時(shí)發(fā)送消息 Winsock1.SendData Text4.Text End Sub Private Sub Winsock1_DataArrival(ByValbytes Total As Long) Dim myStr As String '接收數(shù)據(jù) Winsock1.GetData myStr '將接收到的數(shù)據(jù)顯示在文本框中 Text5.Text = myStr End Sub 運(yùn)行方法:在連個(gè)工程里分別創(chuàng)建兩端窗體,同時(shí)運(yùn)行兩個(gè)實(shí)例,然后, 將一個(gè)應(yīng)用程序的遠(yuǎn)程端口號設(shè)置成為另一個(gè)應(yīng)用程序的本地端口號,然后單擊 “連接”按鈕,就可以實(shí)現(xiàn)兩個(gè)程序之間的通信了。 |
|
|