最近在用VB寫多用戶類型的遠程控制,轉個文章做思路……
轉自: http://www.ibiancheng.cn/Article/VBNetArticle/200804/123.html
普通的講解WINSOCK控件等網絡控件的用法的資料中,無論是使用TCP還是UDP,客戶端程序連接服務端程序時,無一例外的要指定IP地址(或機器名)和端口號,那么,在端口已知而服務端程序所在機器地址或名稱未知的情況下,怎樣實現客戶端程序自動取得服務端IP並建立連接呢,筆者在實際編程中遇到了這種情況,並使用以下方法解決了這個問題。
這種方法就是服務器端添加兩個Winsock控件,一個作為服務端,一個以UDP來廣播本機IP,客戶端也用UDP方式取得服務器IP,然后再將客戶端改為TCP方式來向服務器發起連接。完整代碼如下:
'
服務器端程序加代碼(程序出處www.ibiancheng.cn)
' 新建一個工程,然后在窗體上放兩個個Winsock控件,名為Winsock1和Winsock2
' 一個定時器控件Timer1,Interval屬性設置為1000(也可以自己設置)
' ---------------------向整個網絡廣播本機IP---------------------------
Dim MeIp As String ' 儲存本機IP
Dim netmask As String ' 儲存本機廣播地址
Dim maxconnext As Long
Dim nowconnext() As Boolean
' ---------------------------------------------------------
Private Sub Form_Load()
Winsock1.Protocol = sckUDPProtocol
Winsock1.RemotePort = 9400 ' 綁頂遠程端口號9400
MeIp = Winsock1.LocalIP ' 獲得本機IP地址
netmask = " 127.0.0.255 " ' 為本機廣播地址,廣播地址請按自己的IP計算
' -----------------------------------------
Winsock2( 0).LocalPort = 1001
Winsock2( 0).Listen
End Sub
' -----------------------開始向整個網絡廣播本機IP--------------------------
Private Sub Timer1_Timer() ' 向本網廣播地址發送信息
Winsock1.RemoteHost = netmask ' 向本網廣播地址發送信息,內容是本機的IP地址
Winsock1.SendData MeIp
End Sub
Private Sub Winsock2_Close(Index As Integer)
Winsock2(Index).Close
Winsock2(Index).LocalPort = 1001
Winsock2(Index).Listen
End Sub
' 服務器端收到客戶端的連接請求,這里的代碼可能有點問題,請自己重新寫或聯系我
Private Sub Winsock2_ConnectionRequest(Index As Integer, ByVal requestID As Long)
On Error Resume Next
Dim i As Long
If Index = 0 Then ' 主Winsock——Winsock(0)發生消息
i = 1
While i <= maxconnext And nowconnext(i) ' 在以前的Winsock中找到空閑的Winsock
i = i + 1
DoEvents
Wend
If i <= maxconnext Then ' 在當前裝載的Socket中發現有用戶已經離開
Winsock2(i).LocalPort = 0 ' 使用現成的Socket
Winsock2(i).Accept requestID ' 接收
nowconnext(i) = True ' Winsock(i)被占用
Else ' 在當前裝載的Socket中沒發現有用戶離開
maxconnext = maxconnext + 1 ' 當前接收端口增加
Load Winsock2(maxconnext) ' 生成新的’ Winsock
Winsock2(maxconnext).LocalPort = 0
Winsock2(maxconnext).Accept requestID ' 接收
ReDim Preserve nowconnext(maxconnext + 1)
nowconnext(maxconnext) = True
End If
End If
End Sub
' -------------------------------------------------------
' 客戶端程序(程序出處www.ibiancheng.cn)
' 新建一個工程,然后在窗體上放一個Winsock控件,名為Winsock1
' -----------------------------
Dim CanSend As String ' 保存服務端IP
' ----------------------------
Private Sub Form_Load()
' --------------------------------------
Winsock1.Protocol = sckUDPProtocol ' 初始化連接方式
Winsock1.Bind " 9400 " ' 從9400端口偵聽
' ----------------------------------------
Winsock2.RemoteHost = " 1001 "
End Sub
' -----------------------------------------------------------
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
DoEvents
Dim DataArrival As String
Dim Cip As String
Winsock1.GetData DataArrival
CanSend = DataArrival ' 取得服務端IP
Winsock1.Close ' 斷開連接
Winsock1.LocalPort = 0 ' 改端口號為0
Winsock1.Protocol = sckTCPProtocol ' 改變連接方式
Winsock1.RemotePort = 1001 ' 設置服務器端口號
Winsock1.RemoteHost = CanSend ' 請求連接服務器
Winsock1.Connect
End Sub
' 新建一個工程,然后在窗體上放兩個個Winsock控件,名為Winsock1和Winsock2
' 一個定時器控件Timer1,Interval屬性設置為1000(也可以自己設置)
' ---------------------向整個網絡廣播本機IP---------------------------
Dim MeIp As String ' 儲存本機IP
Dim netmask As String ' 儲存本機廣播地址
Dim maxconnext As Long
Dim nowconnext() As Boolean
' ---------------------------------------------------------
Private Sub Form_Load()
Winsock1.Protocol = sckUDPProtocol
Winsock1.RemotePort = 9400 ' 綁頂遠程端口號9400
MeIp = Winsock1.LocalIP ' 獲得本機IP地址
netmask = " 127.0.0.255 " ' 為本機廣播地址,廣播地址請按自己的IP計算
' -----------------------------------------
Winsock2( 0).LocalPort = 1001
Winsock2( 0).Listen
End Sub
' -----------------------開始向整個網絡廣播本機IP--------------------------
Private Sub Timer1_Timer() ' 向本網廣播地址發送信息
Winsock1.RemoteHost = netmask ' 向本網廣播地址發送信息,內容是本機的IP地址
Winsock1.SendData MeIp
End Sub
Private Sub Winsock2_Close(Index As Integer)
Winsock2(Index).Close
Winsock2(Index).LocalPort = 1001
Winsock2(Index).Listen
End Sub
' 服務器端收到客戶端的連接請求,這里的代碼可能有點問題,請自己重新寫或聯系我
Private Sub Winsock2_ConnectionRequest(Index As Integer, ByVal requestID As Long)
On Error Resume Next
Dim i As Long
If Index = 0 Then ' 主Winsock——Winsock(0)發生消息
i = 1
While i <= maxconnext And nowconnext(i) ' 在以前的Winsock中找到空閑的Winsock
i = i + 1
DoEvents
Wend
If i <= maxconnext Then ' 在當前裝載的Socket中發現有用戶已經離開
Winsock2(i).LocalPort = 0 ' 使用現成的Socket
Winsock2(i).Accept requestID ' 接收
nowconnext(i) = True ' Winsock(i)被占用
Else ' 在當前裝載的Socket中沒發現有用戶離開
maxconnext = maxconnext + 1 ' 當前接收端口增加
Load Winsock2(maxconnext) ' 生成新的’ Winsock
Winsock2(maxconnext).LocalPort = 0
Winsock2(maxconnext).Accept requestID ' 接收
ReDim Preserve nowconnext(maxconnext + 1)
nowconnext(maxconnext) = True
End If
End If
End Sub
' -------------------------------------------------------
' 客戶端程序(程序出處www.ibiancheng.cn)
' 新建一個工程,然后在窗體上放一個Winsock控件,名為Winsock1
' -----------------------------
Dim CanSend As String ' 保存服務端IP
' ----------------------------
Private Sub Form_Load()
' --------------------------------------
Winsock1.Protocol = sckUDPProtocol ' 初始化連接方式
Winsock1.Bind " 9400 " ' 從9400端口偵聽
' ----------------------------------------
Winsock2.RemoteHost = " 1001 "
End Sub
' -----------------------------------------------------------
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
DoEvents
Dim DataArrival As String
Dim Cip As String
Winsock1.GetData DataArrival
CanSend = DataArrival ' 取得服務端IP
Winsock1.Close ' 斷開連接
Winsock1.LocalPort = 0 ' 改端口號為0
Winsock1.Protocol = sckTCPProtocol ' 改變連接方式
Winsock1.RemotePort = 1001 ' 設置服務器端口號
Winsock1.RemoteHost = CanSend ' 請求連接服務器
Winsock1.Connect
End Sub
主要用到的方法就是UDP廣播
本文結束,原理粗淺望能起拋磚引玉之用。