Получить Ip-адрес сервера из обычной ссылки - VB

Узнай цену своей работы

Формулировка задачи:

Добрый день! Вроде задача вполне реализуемая (тем более что в моем случае ссылка уже содержит этот ip), но хочется сделать грамотно! Есть ссылка: http://yandex.ru/internet Хочется вычислить Ip Яндекса в чистом виде из этой ссылки. Как? Спасибо!)

Решение задачи: «Получить Ip-адрес сервера из обычной ссылки»

textual
Листинг программы
  1. Option Explicit
  2.  
  3. Const WSADESCRIPTION_LEN As Long = 256&
  4. Const WSASYS_STATUS_LEN As Long = 128&
  5.  
  6. Private Type wsaData
  7.     wVersion As Integer
  8.     wHighVersion As Integer
  9.     szDescription(WSADESCRIPTION_LEN + 1) As Byte
  10.     szSystemStatus(WSADESCRIPTION_LEN + 1) As Byte
  11.     iMaxSockets As Integer
  12.     iMaxUdpDg As Integer
  13.     lpVendorInfo As Long
  14. End Type
  15.  
  16. Private Type hostent
  17.     h_name As Long
  18.     h_aliases As Long
  19.     h_addrtype As Integer
  20.     h_length As Integer
  21.     h_addr_list As Long
  22. End Type
  23.  
  24. Private Type in_addr
  25.     oct_1 As Byte
  26.     oct_2 As Byte
  27.     oct_3 As Byte
  28.     oct_4 As Byte
  29. End Type
  30.  
  31. Private Declare Function WSAStartup Lib "Ws2_32.dll" (ByVal wVersionRequested As Integer, lpWSAData As wsaData) As Long
  32. Private Declare Function WSACleanup Lib "Ws2_32.dll" () As Long
  33. Private Declare Function WSAGetLastError Lib "Ws2_32.dll" () As Long
  34.  
  35. Private Declare Function inet_addr Lib "Ws2_32.dll" (ByVal cp As Long) As in_addr  'Windows Vista +
  36. Private Declare Function inet_ntoa Lib "Ws2_32.dll" (ByVal Addr As Long) As Long  'Windows Vista +
  37. Private Declare Function gethostbyname Lib "Ws2_32.dll" (ByVal lpCharName As Long) As Long  'Windows Vista +
  38. Private Declare Function gethostbyaddr Lib "Ws2_32.dll" (ByVal lpCharAddr As Long, ByVal llen As Long, ByVal ltype As Long) As Long  'Windows Vista +
  39. 'Private Declare Function RtlIpv4AddressToString Lib "Ntdll.dll" Alias "RtlIpv4AddressToStringA" (ptAddr As Long, ByVal S As Long) As Long  'Windows Vista +
  40.  
  41. Private Declare Function memcpy Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal length As Long) As Long
  42. Private Declare Function FormatMessage Lib "kernel32.dll" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Long, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Any) As Long
  43. Private Declare Function lstrlenA Lib "kernel32.dll" (ByVal lpString As Long) As Long
  44. Private Declare Function lstrcpyA Lib "kernel32.dll" (ByVal lpString1 As Long, ByVal lpString2 As Long) As Long
  45. Private Declare Function GetMem4 Lib "msvbvm60" (pSrc As Any, pDst As Any) As Long
  46.  
  47. Private Const AF_INET As Long = 2
  48.  
  49.  
  50. Private Sub Form_Load()
  51.     ResolveHost "i.ua"
  52.     ResolveHost "-"
  53.     ResolveHost "255.1.1.1"
  54.     ResolveHost "91.198.36.14"
  55.     ResolveHost "https://yandex.ua/maps"
  56.     ResolveHost "8.8.4.4:8080"
  57.     Unload Me
  58. End Sub
  59.  
  60. Function ResolveHost(ByVal Host_name As String)
  61.     Dim wVersionRequested As Integer
  62.     Dim dwErr As Long
  63.     Dim wsaData As wsaData
  64.     Dim remoteHost As hostent
  65.     Dim lpRemoteHost As Long
  66.     Dim i_addr As in_addr
  67.     Dim pHost_NameA As Long
  68.     Dim sAddr As String
  69.  
  70.     Debug.Print "-----------------------------------"
  71.  
  72.     'Extracting the host name
  73.    Host_name = ExtractHost(Host_name)
  74.  
  75.     wVersionRequested = 2& * 256 + 2    '(WinSock ver. 2.2.)
  76.  
  77.     dwErr = WSAStartup(wVersionRequested, wsaData)
  78.     If (dwErr <> 0) Then
  79.         MsgBox "WSAStartup failed with error: " & dwErr
  80.         Exit Function
  81.     End If
  82.    
  83.     'Confirm that the WinSock DLL supports 2.2.
  84.    If ((wsaData.wVersion And 255&) <> 2) Or ((wsaData.wVersion \ 256&) <> 2) Then
  85.         MsgBox "Could not find a usable version of Winsock.dll"
  86.         GoTo Finally
  87.     End If
  88.  
  89.     pHost_NameA = StrPtr(StrConv(Host_name, vbFromUnicode)) 'WSTR -> *char[]
  90.  
  91.     ' If the user input is an alpha name for the host, use gethostbyname()
  92.    ' If not, get host by addr (assume IPv4)
  93.    
  94.     If Host_name Like "*[!0-9.]*" Then  'host address is a name
  95.        Debug.Print "By Name. Calling gethostbyname with " & Host_name
  96.  
  97.         lpRemoteHost = gethostbyname(pHost_NameA)
  98.        
  99.         If 0 = lpRemoteHost Then
  100.             dwErr = Err.LastDllError
  101.             Debug.Print "Error #" & dwErr & ". " & WSA_MessageText(dwErr)
  102.             'Debug.Print WSAGetLastError()  ' it seems WSAGetLastError doesn't work inside vbvm; err.LastDllError redirects its code instead.
  103.            GoTo Finally
  104.         End If
  105.     Else
  106.         Debug.Print "By Address. Calling gethostbyaddr with " & Host_name
  107.        
  108.         i_addr = inet_addr(pHost_NameA)  'ipv4 validation
  109.        
  110.         ' INADDR_NONE (-1)
  111.        If i_addr.oct_1 = 255 And i_addr.oct_2 = 255 And i_addr.oct_3 = 255 And i_addr.oct_4 = 255 Then
  112.             MsgBox "The IPv4 address entered must be a legal address"
  113.             GoTo Finally
  114.         End If
  115.        
  116.         lpRemoteHost = gethostbyaddr(VarPtr(i_addr), 4, AF_INET)    'ipv4 type  (possible values = ipv4, ipv6, NETBIOS)
  117.        
  118.         If 0 = lpRemoteHost Then
  119.             dwErr = Err.LastDllError
  120.             Debug.Print "Error #" & dwErr & ". " & WSA_MessageText(dwErr)
  121.             GoTo Finally
  122.         End If
  123.     End If
  124.    
  125.     If 0 <> lpRemoteHost Then
  126.         memcpy remoteHost, ByVal lpRemoteHost, LenB(remoteHost)     ' * -> struct
  127.        
  128.         Debug.Print "Official name: " & GetStringFromPtrA(remoteHost.h_name)
  129.        
  130.         Dim PtArr   As Long
  131.         Dim ptAddr  As Long
  132.         Dim PtChar  As Long
  133.         Dim Addr    As Long
  134.        
  135.         PtArr = remoteHost.h_addr_list
  136.        
  137.         Do
  138.             GetMem4 ByVal PtArr, ptAddr ' *addr for each element
  139.            
  140.             If ptAddr <> 0 Then
  141.            
  142.                 GetMem4 ByVal ptAddr, Addr
  143.            
  144.                 PtChar = inet_ntoa(Addr)  'addr -> *char[]
  145.                If PtChar <> 0 Then
  146.                     Debug.Print "Address: " & GetStringFromPtrA(PtChar)
  147.                 End If
  148.                
  149. '                sAddr = String$(8, vbNullChar)  'at least 16 chars
  150. '                dwErr = RtlIpv4AddressToString(ByVal ptAddr, StrPtr(sAddr))
  151. '                sAddr = StrConv(sAddr, vbUnicode)
  152. '                Debug.Print "Address: " & sAddr
  153.            End If
  154.             PtArr = PtArr + 4
  155.         Loop While ptAddr <> 0
  156.     End If
  157.    
  158. Finally:
  159.     WSACleanup
  160. End Function
  161.  
  162. Function GetStringFromPtrA(Ptr As Long) As String
  163.     Dim Size As Long
  164.     Dim sText As String
  165.     If Ptr <> 0 Then
  166.         Size = lstrlenA(Ptr)
  167.         If Size > 0 Then
  168.             sText = String$(Size \ 2 + 1, vbNullChar)
  169.             lstrcpyA StrPtr(sText), Ptr
  170.             GetStringFromPtrA = Left$(StrConv(sText, vbUnicode), Size)
  171.         End If
  172.     End If
  173. End Function
  174.  
  175. Private Function WSA_MessageText(lCode As Long) As String
  176.     Const MAX_PATH As Long = 260&
  177.     Const FORMAT_MESSAGE_FROM_SYSTEM    As Long = &H1000&
  178.     Const FORMAT_MESSAGE_IGNORE_INSERTS As Long = &H200
  179.     Const WSANO_DATA As Long = 11004
  180.     Const WSAHOST_NOT_FOUND As Long = 11001
  181.    
  182.     Dim sRtrnCode   As String
  183.     Dim lRet        As Long
  184.    
  185.     Select Case lCode
  186.         Case WSAHOST_NOT_FOUND
  187.             WSA_MessageText = "Host not found"
  188.         Case WSANO_DATA
  189.             WSA_MessageText = "No data record found"
  190.         Case Else
  191.             sRtrnCode = Space$(MAX_PATH)
  192.             lRet = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, ByVal 0&, lCode, ByVal 0&, sRtrnCode, MAX_PATH, ByVal 0&)
  193.             If lRet > 0 Then
  194.                 WSA_MessageText = Left$(sRtrnCode, lRet)
  195.                 WSA_MessageText = Replace$(WSA_MessageText, vbCrLf, vbNullString)
  196.             End If
  197.     End Select
  198. End Function
  199.  
  200. ' Вытягивает из строки адрес хоста для HTTP-адреса
  201. Public Function ExtractHost(sText As String) As String
  202.     On Error GoTo ErrorHandler
  203.     Dim S        As String
  204.     Dim pos      As Long
  205.     Dim pos2     As Long
  206.     Dim oRegEx   As Object
  207.     Dim oMatches As Object
  208.    
  209.     Set oRegEx = CreateObject("VBScript.RegExp")
  210.     oRegEx.Pattern = """?(http:|www(2)?\.|https:)[^ \r\n""]*( |""|$|\r|\n)"
  211.     Set oMatches = oRegEx.Execute(sText)
  212.     If oMatches.Count = 0 Then
  213.         ExtractHost = sText
  214.         GoTo Finally
  215.     End If
  216.     S = UnQuote(oMatches.Item(0).Value)
  217.    
  218.     ' - 0x0D 0x0A
  219.    If Right$(S, 1) = Chr$(10) Then S = Left$(S, Len(S) - 1)
  220.     If Right$(S, 1) = Chr$(13) Then S = Left$(S, Len(S) - 1)
  221.    
  222.     ' - http://
  223.    If StrComp(Left$(S, 5), "http:", 1) = 0 Then
  224.         S = Mid$(S, 8)
  225.     ' - https://
  226.    ElseIf StrComp(Left$(S, 6), "https:", 1) = 0 Then
  227.         S = Mid$(S, 9)
  228.     End If
  229.    
  230.     ' - www.
  231.    If StrComp(Left$(S, 4), "www.", 1) = 0 Then
  232.         S = Mid$(S, 5)
  233.     ' - www2.
  234.    ElseIf StrComp(Left$(S, 5), "www2.", 1) = 0 Then
  235.         S = Mid$(S, 6)
  236.     End If
  237.    
  238.     ' / с конца
  239.    pos = InStr(S, "/")
  240.     pos2 = InStr(S, "")
  241.     If pos = 0 And pos2 = 0 Then
  242.         ExtractHost = S
  243.     Else
  244.         If pos <> 0 And pos2 <> 0 Then
  245.             ExtractHost = Left$(S, IIf(pos < pos2, pos - 1, pos2 - 1))
  246.         ElseIf pos <> 0 Then
  247.             ExtractHost = Left$(S, pos - 1)
  248.         Else
  249.             ExtractHost = Left$(S, pos2 - 1)
  250.         End If
  251.     End If
  252.  
  253. Finally:
  254.     ' remove :port
  255.    oRegEx.Pattern = ".*:\d+$"
  256.     Set oMatches = oRegEx.Execute(ExtractHost)
  257.     If oMatches.Count <> 0 Then
  258.         ExtractHost = Left$(ExtractHost, InStrRev(ExtractHost, ":") - 1)
  259.     End If
  260.    
  261.     Exit Function
  262. ErrorHandler:
  263.     Debug.Print Now, Err, "Parser.ExtractHost"
  264. End Function
  265.  
  266. Public Function UnQuote(str As String) As String   ' Убрать кавычки (слева и справа)
  267.    On Error GoTo ErrorHandler
  268.     Dim S As String: S = str
  269.     Do While Left$(S, 1&) = """"
  270.         S = Mid$(S, 2&)
  271.     Loop
  272.     Do While Right$(S, 1&) = """"
  273.         S = Left$(S, Len(S) - 1&)
  274.     Loop
  275.     UnQuote = S
  276.     Exit Function
  277. ErrorHandler:
  278.     Debug.Print Now, Err, "Parser.UnQuote", "String: ", str
  279. End Function

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 3.8 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы