[轉]vb socket通信(TCP/UDP)一對一、多對一


VB Socket編程(Winsock控件創建TCP/IP客戶機/服務器程序)
 
   Winsock控件建立在TCP、UDP協議的基礎上,完成與遠程計算機的通信。即使對TCP/IP不太熟悉的用戶,使用該控件也可以在十幾分鍾內創建一 個簡單的客戶機/服務器程序。下面我們對Winsock控件的事件、方法、屬性按其在程序中出現的順序分別作詳細的介紹,以便更好地理解程序源代碼。
下面是Winsock控件的相關屬性,方法和事件。(略去一些暫用不到的)
*屬性


-------------------------------------------------------------------------
LocalHostName >
先在一台計算機上運行服務器程序,此時窗口上只有一個“退出”按鈕。 再在另一台計算機上運行客戶機程序,在“連接”按鈕右邊的文本框中輸入服務器的主機名后單擊“連接”按鈕。如果連接成功,則服務器和客戶機程序窗口都會出 現兩個文本框。這時,兩端都可以在上面的文本框中輸入文字,這些文字會立即在下面的文本框中出現。
服務器程序使用的控件如下:
(1)Command1:退出按鈕;
(2)textsend:發送數據文本框;
(3)Winsockserver: 服務器Winsock;
(4)textget :接收數據文本框。
服務器程序的界面如圖所示。

 

服務器程序的源代碼如下:

[vb]  view>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:接收數據文本框;   
客戶機程序的源代碼如下:

[vb]  view>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  
     
建立多個客戶端

 

 
           
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 控件必須顯式地進行“監聽”,另一個必須使用 Connect 方法初始化連接。

UDP 協議不需要顯式的連接。要在兩個控件中間發送數據,需要完成以下的三步(在連接的雙方):

  1. 將 RemoteHost 屬性設置為另一台計算機的名稱。

     
  2. 將 RemotePort 屬性設置為第二個控件的 LocalPort 屬性。

     
  3. 調用 Bind 方法,指定使用的 LocalPort。(下面將詳細地討論該方法。)

因為兩台計算機的地位可以看成“平等的”,這種應用程序也被稱為點到點的。為了具體說明這個問題,下面將創建一個“聊天”應用程序,兩個人可以通過它進行實時的交談。

要創建一個 UDP 伙伴,請按照以下步驟執行:

  1. 創建一個新的 Standard EXE 工程。
     
  2. 將缺省的窗體的名稱修改為 frmPeerA。
     
  3. 將窗體的標題修改為“Peer A”。
     
  4. 在窗體中放入一個 Winsock 控件,並將其命名為 udpPeerA。
     
  5. 在“屬性”頁上,單擊“協議”並將協議修改為 UDPProtocol。
     
  6. 在窗體中添加兩個 TextBox 控件。將第一個命名為 txtSend,第二個命名為 txtOutput。
     
  7. 為窗體增加如下的代碼。
VBScript code 復制代碼
Private Sub Form_Load()
    '控件的名字為 udpPeerA
    With udpPeerA
        '重點:必須將 RemoteHost 的值
        '修改為計算機的名字。
        .RemoteHost = "PeerB"
        .RemotePort = 1001 '連接的端口號。
        .Bind 1002 '綁定到本地的端口。
    End With
    frmPeerB.Show '顯示第二個窗體。
End Sub

Private Sub txtSend_Change()
    '在鍵入文本時,立即將其發送出去。
   >Text
End Sub

Private Sub udpPeerA_DataArrival _
        (ByVal bytesTotal As Long)
    Dim strData As String
   >Text = strData
End Sub

要創建第二個 UDP 伙伴,請按照以下步驟執行:

  1. 在工程中添加一個標准窗體。
     
  2. 將窗體的名字修改為 frmPeerB。
     
  3. 將窗體的標題修改為“Peer B”。
     
  4. 在窗體中放入一個 Winsock 控件,並將其命名為 udpPeerB。
     
  5. 在“屬性”頁上,單擊“協議”並將協議修改為“UDPProtocol”。
     
  6. 在窗體上添加兩個 TextBox 控件。將第一個命名為 txtSend,第二個命名為 txtOutput。
     
  7. 在窗體中添加如下的代碼。
VBScript code 復制代碼
Private Sub Form_Load()
    '控件的名字為 udpPeerB。
    With udpPeerB
        '重點:必須將 RemoteHost 的值改為
        '計算機的名字。
        .RemoteHost = "PeerA"
        .RemotePort = 1002 '要連接的端口。
        .Bind 1001 '綁定到本地的端口上。
    End With
End Sub

Private Sub txtSend_Change()
    '在鍵入后立即發送文本。
   >Text
End Sub

Private Sub udpPeerB_DataArrival _
        (ByVal bytesTotal As Long)
    Dim strData As String
   >Text = strData
End Sub

如果要試用上面的例子,按 F5 鍵運行工程,然后在兩個窗體的 txtSend TextBox 中分別鍵入一些文本。鍵入的文字將出現在另一個窗體的 txtOutput TextBox 中。

關於 Bind 方法

在上面的代碼中,在創建 UDP 應用程序時調用了 Bind 方法,這是必須的。Bind 方法的作用是為控件“保留”一個本地端口。例如,如果將控件綁定到 1001 號端口,那么其它應用程序將不能使用該端口進行“監聽”。該方法阻止其它應用程序使用同樣的端口。

Bind 方法的第二個參數是任選的。如果計算機上存在多個網絡適配器,可以用 LocalIP 參數來指定使用哪一個適配器。如果忽略該參數,控件使用的將是計算機上“控制面板”設置中“網絡”控制面板對話框中列出的第一個適配器。

在使用 UDP 協議的時候,可以任意地改變 RemoteHost 和 RemotePort 屬性,同時始終保持綁定在同一個 LocalPort 上。TCP 協議與此不同,在改變 RemoteHost 和 RemotePort 屬性之前,必須先關閉連接。

 
————————————————————————————————————————————————————————————————————-
以上為介紹,可以有個大概的了解,也是轉載的,不過當時情況混亂,沒有附鏈接……
以下為完整的一個多對一的TCP通信實例,感謝原作者的幫助!轉自: http://www.cnblogs.com/findw/archive/2012/06/22/2558876.html
—————————————————————————————————————————————————————————————————————
 
 
[vb]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1.  1 通信程序通常都是采用Client/Server形式。這就要求作為服務器的主機可以同時處理多個客戶的請求。因此在編寫服務器程序時要添加多個Winsock控件。在開始我們先加入兩個Winsock控件。其中一個用來偵聽網上請求信號,取名為Listener;另外一個為初始的連接口,取名叫Sock(0)。注意,后一個控件要設為動態數組的形式,以后當客戶增多時,可在這個控件基礎上動態增加。由於受資源限制,我們在本例中設定最多可以同時接納15個客戶。客戶機一般只與一個主機相連,因此程序只須一個Winsock進行連接就足夠了。這個程序要用到的控件較少,除了Winsock和Form控件外,只須再添加Commmand控件即可。下面是具體程序和詳細注釋。   
  2.   2 ******************************   
  3.   3 '服務器程序   
  4.   4 ******************************   
  5.   5 Option Explicit   
  6.   6 定義常量   
  7.   7 Const BUSY As Boolean = False   
  8.   8 Const FREE As Boolean = True   
  9.   9 定義連接狀態   
  10.  10 Dim ConnectState() As Boolean   
  11.  11 Private Sub Form_Load()   
  12.  12 ReDim Preserve ConnectState(0 To 1)   
  13.  13 On Error Resume Next   
  14.  14 ConnectState(0) = FREE   
  15.  15 ConnectState(1) = FREE   
  16.  16 '指定網絡端口號   
  17.  17 Listener.LocalPort = 1011   
  18.  18 '開始偵聽   
  19.  19 Listener.Listen   
  20.  20 End Sub   
  21.  21 Private Sub Listener_ConnectionRequest(ByVal requestID As Long)   
  22.  22 Dim SockIndex As Integer   
  23.  23 Dim SockNum As Integer   
  24.  24 On Error Resume Next   
  25.  25 Form1.Print requestID & "連接請求"   
  26.  26 '查找連接的用戶數   
  27.  27 SockNum = UBound(ConnectState)   
  28.  28 If SockNum > 14 Then   
  29.  29 Form1.Print SockIndex & ""   
  30.  30 Exit Sub   
  31.  31 End If   
  32.  32 '查找空閑的sock   
  33.  33 SockIndex = FindFreeSocket()   
  34.  34 '如果已有的sock都忙,而且sock數不超過15個,動態添加sock   
  35.  35 If SockIndex > SockNum Then   
  36.  36 Load Sock(SockIndex)   
  37.  37 End If   
  38.  38 ConnectState(SockIndex) = BUSY   
  39.  39 Sock(SockIndex).Tag = SockIndex   
  40.  40 '接受請求   
  41.  41 Sock(SockIndex).Accept (requestID)   
  42.  42 Form1.Print SockIndex & "接受請求"   
  43.  43 End Sub   
  44.  44   
  45.  45 '客戶斷開,關閉相應的sock   
  46.  46 Private Sub Sock_Close(Index As Integer)   
  47.  47 If Sock(Index).State <> sckClosed Then   
  48.  48 Sock(Index).Close   
  49.  49 End If   
  50.  50 ConnectState(Index) = FREE   
  51.  51 Form1.Print Index & "close"   
  52.  52 End Sub   
  53.  53   
  54.  54 '接收數據   
  55.  55 Private Sub Sock_DataArrival(Index As Integer, ByVal bytesTotal As Long)   
  56.  56 Dim dx As Double   
  57.  57 Form1.Print "數據來自" & Index   
  58.  58 Sock(Index).GetData dx, vbDouble   
  59.  59 Form1.Print "dx=" & dx   
  60.  60 End Sub   
  61.  61   
  62.  62 '尋找空閑的sock   
  63.  63 Public Function FindFreeSocket()   
  64.  64 Dim SockCount, i As Integer   
  65.  65 SockCount = UBound(ConnectState)   
  66.  66 For i = 0 To SockCount   
  67.  67 If ConnectState(i) = FREE Then   
  68.  68 FindFreeSocket = i   
  69.  69 Exit Function   
  70.  70 End Ifs   
  71.  71 Next i   
  72.  72 ReDim Preserve ConnectState(0 To SockCount + 1)   
  73.  73 FindFreeSocket = UBound(ConnectState)   
  74.  74 End Function   
  75.  75   
  76.  76 ***************************   
  77.  77 '客戶程序   
  78.  78 ’***************************   
  79.  79 Option Explicit   
  80.  80 '發送數據   
  81.  81 Private Sub command1_Click()   
  82.  82 Dim dx As Double   
  83.  83 dx = 23.9   
  84.  84 sock.SendData dx   
  85.  85 MsgBox ("data sended")   
  86.  86 End Sub   
  87.  87   
  88.  88 Private Sub Form_Load()   
  89.  89 '遠程主機名   
  90.  90 sock.RemoteHost = "media2"   
  91.  91 '網絡端口   
  92.  92 sock.RemotePort = 1011   
  93.  93 '發出連接命令   
  94.  94 sock.Connect   
  95.  95 Command1.Enabled = False   
  96.  96 End Sub   
  97.  97   
  98.  98 '服務器關閉   
  99.  99 Private Sub sock_Close()   
  100. 100 MsgBox ("socket closed")   
  101. 101 End Sub   
  102. 102   
  103. 103 '連接成功   
  104. 104 Private Sub sock_Connect()   
  105. 105 MsgBox ("socket connected")   
  106. 106 Command1.Enabled = True   
  107. 107 End Sub  
  108. 復制代碼  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM