Public Class SockProxy
Private m_RequireAuthorize As Boolean = False
Private m_user As String = String.Empty
Private m_pass As String = String.Empty
''' <summary>
''' 读取或设置代理是否需要认证
''' </summary>
''' <value>是否要认证</value>
''' <returns></returns>
''' <remarks></remarks>
Property RequireAuthorize() As Boolean
Get
Return m_RequireAuthorize
End Get
Set(ByVal value As Boolean)
m_RequireAuthorize = value
End Set
End Property
''' <summary>
''' 读取或设置代理的用户名
''' </summary>
''' <value>用户名</value>
''' <returns></returns>
''' <remarks></remarks>
Property Username() As String
Get
Return m_user
End Get
Set(ByVal value As String)
Me.m_user = value
End Set
End Property
''' <summary>
''' 读取或设置代理的密码
''' </summary>
''' <value>密码</value>
''' <returns></returns>
''' <remarks></remarks>
Property Password() As String
Get
Return Me.m_pass
End Get
Set(ByVal value As String)
Me.m_pass = value
End Set
End Property
''' <summary>
''' 连接代理
''' </summary>
''' <param name="strRemoteHost">要访问的IP</param>
''' <param name="iRemotePort">要访问的端口</param>
''' <param name="sProxyServer">代理的socket</param>
''' <returns>是否成功</returns>
''' <remarks></remarks>
Function ConnectProxyServer(ByVal strRemoteHost As String, ByVal iRemotePort As Integer, ByVal sProxyServer As socket) As Boolean
Dim bySock5Send(9) As Byte
Dim bySock5Receive(9) As Byte
'构造Socks5代理服务器第一连接头(无用户名密码)
bySock5Send(0) = 5
bySock5Send(1) = 1
bySock5Send(2) = IIf(Me.RequireAuthorize, 2, 0)
'发送Socks5代理第一次连接信息
sProxyServer.Send(bySock5Send, 3, SocketFlags.None)
Dim iRecCount As Integer = sProxyServer.Receive(bySock5Receive, bySock5Receive.Length, SocketFlags.None)
'用户验证
If bySock5Receive(1) = 2 And Me.RequireAuthorize = False Then
Throw New Exception("代理服务器需要进行身份确认。")
ElseIf bySock5Receive(1) = 2 Then
'构造Socks5代理服务器第一连接头(无用户名密码)
Dim bUser() As Byte = Encoding.Default.GetBytes(Username)
Dim bPass() As Byte = Encoding.Default.GetBytes(Password)
Dim dl As Integer = 3 + bUser.Length + bPass.Length
ReDim bySock5Send(dl - 1)
bySock5Send(0) = 5
bySock5Send(1) = bUser.Length
Array.Copy(bUser, 0, bySock5Send, 2, bUser.Length)
bySock5Send(2 + bUser.Length) = bPass.Length
Array.Copy(bPass, 0, bySock5Send, 3 + bUser.Length, bPass.Length)
'发送Socks5代理第一次连接信息
sProxyServer.Send(bySock5Send, dl, SocketFlags.None)
ReDim bySock5Receive(100)
iRecCount = sProxyServer.Receive(bySock5Receive, bySock5Receive.Length, SocketFlags.None)
If (iRecCount < 2) Then
sProxyServer.Close()
Throw New Exception("不能获得代理服务器正确响应。")
End If
If (bySock5Receive(0) <> 5 Or (bySock5Receive(1) <> 0 And bySock5Receive(1) <> 2)) Then
sProxyServer.Close()
Throw New Exception("代理服务其返回的响应错误。")
End If
If bySock5Receive(1) = 0 Then
ReDim bySock5Send(9)
bySock5Send(0) = 5
bySock5Send(1) = 1
bySock5Send(2) = 0
bySock5Send(3) = 1
Dim ipAdd As IPAddress = Dns.GetHostAddresses(strRemoteHost)(0)
Dim strIp As String = ipAdd.ToString
Dim strAryTemp() As String = strIp.Split("."c)
bySock5Send(4) = Convert.ToByte(strAryTemp(0))
bySock5Send(5) = Convert.ToByte(strAryTemp(1))
bySock5Send(6) = Convert.ToByte(strAryTemp(2))
bySock5Send(7) = Convert.ToByte(strAryTemp(3))
bySock5Send(8) = iRemotePort / 256
bySock5Send(9) = iRemotePort Mod 256
sProxyServer.Send(bySock5Send, bySock5Send.Length, SocketFlags.None)
iRecCount = sProxyServer.Receive(bySock5Receive, bySock5Receive.Length, SocketFlags.None)
If (bySock5Receive(0) <> 5 Or bySock5Receive(1) <> 0) Then
sProxyServer.Close()
Throw New Exception("第二次连接Socks5代理返回数据出错。")
End If
Return True
Else
If (bySock5Receive(1) = 2) Then
Throw New Exception("代理服务器需要进行身份确认。")
Else
Return False
End If
End If
End If
End Function
End Class