最近在用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广播
本文结束,原理粗浅望能起抛砖引玉之用。