一个对等局域网多台机器共用一条ADSL线,MODEM不是连在我的机器上的,我如何能得到外网的IP地址?使用哪个API?

解决方案 »

  1.   

    modem不在你的机器上,那说明采用路由方式出去了,那你的公网地址改变成多少同你本机没有关系的,“透明的”。所以通过API是看不到的。
    可以通过ping 外部已知地址知道。如果要编程获得这个IP,你可以:
    1、tracert 然后截取ping结果,本地地址的下一个路由地址就是你的adsl的ip
    譬如距离如下:
       假设你的局域网络缺省路由IP192.168.0.1,你的机器局域IP192.168.250
    tracert www.yahoo.com会有:
      1   <10 ms   <10 ms   <10 ms  PROXYSERVER [192.168.0.1]
      2    60 ms    20 ms    10 ms  218.20.216.1
    看看 192.168.0.1的下一行的ip地址218.20.216.1就是adsl的IP2、通过ICMP协议,查询路由获得,思路同上,但是可以通过API获得结果,具体的我页没有办法写出,查vb ICMP协议 可能会有结果。
      

  2.   


         Private Const WS_VERSION_REQD = &H101 
         Private Const WS_VERSION_MAJOR = WS_VERSION_REQD \ &H100 And &HFF& 
         Private Const WS_VERSION_MINOR = WS_VERSION_REQD And &HFF& 
         Private Const MIN_SOCKETS_REQD = 1 
         Private Const SOCKET_ERROR = -1 
         Private Const WSADescription_Len = 256 
         Private Const WSASYS_Status_Len = 128 
         
         Private Type HOSTENT 
         hName As Long 
         hAliases As Long 
         hAddrType As Integer 
         hLength As Integer 
         hAddrList As Long 
         End Type 
         
         Private Type WSADATA 
         wversion As Integer 
         wHighVersion As Integer 
         szDescription(0 To WSADescription_Len) As Byte 
         szSystemStatus(0 To WSASYS_Status_Len) As Byte 
         iMaxSockets As Integer 
         iMaxUdpDg As Integer 
         lpszVendorInfo As Long 
         End Type 
         
         Private Declare Function WSAGetLastError Lib "WSOCK32.DLL" () As Long 
         Private Declare Function WSAStartup Lib "WSOCK32.DLL" (ByVal _ 
         wVersionRequired&, lpWSAData As WSADATA) As Long 
         Private Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long 
         
         Private Declare Function gethostname Lib "WSOCK32.DLL" (ByVal hostname$,_ 
         ByVal HostLen as Long) as long 
         Private Declare Function gethostbyname Lib "WSOCK32.DLL" (ByVal _ 
         hostname$) As Long 
         Private Declare Sub RtlMoveMemory Lib "KERNEL32" (hpvDest As Any, ByVal_ 
         hpvSource&, ByVal cbCopy&) 
         
         Function hibyte(ByVal wParam As Integer) 
         
         hibyte = wParam \ &H100 And &HFF& 
         
         End Function 
         
         Function lobyte(ByVal wParam As Integer) 
         
         lobyte = wParam And &HFF& 
         
         End Function 
         
         Sub SocketsInitialize() 
         Dim WSAD As WSADATA 
         Dim iReturn As Integer 
         Dim sLowByte As String, sHighByte As String, sMsg As String 
         
         iReturn = WSAStartup(WS_VERSION_REQD, WSAD) 
         
         If iReturn <> 0 Then 
         MsgBox "Winsock.dll is not responding." 
         End 
         End If 
         
         If lobyte(WSAD.wversion) <WS_VERSION_MAJOR Or (lobyte(WSAD.wversion) = _ 
         WS_VERSION_MAJOR And hibyte(WSAD.wversion) < WS_VERSION_MINOR) Then 
         
         sHighByte = Trim$(Str$(hibyte(WSAD.wversion))) 
         sLowByte = Trim$(Str$(lobyte(WSAD.wversion))) 
         sMsg = "Windows Sockets version " & sLowByte & "." & sHighByte 
         sMsg = sMsg & " is not supported by winsock.dll " 
         MsgBox sMsg 
         End 
         End If 
         
         'iMaxSockets is not used in winsock 2. So the following check is only 
         'necessary for winsock 1. If winsock 2 is requested, 
         'the following check can be skipped. 
         
         If WSAD.iMaxSockets < MIN_SOCKETS_REQD Then 
         sMsg = "This application requires a minimum of " 
         sMsg = sMsg & Trim$(Str$(MIN_SOCKETS_REQD)) & " supported sockets." 
         MsgBox sMsg 
         End 
         End If 
         
         End Sub 
         
         Sub SocketsCleanup() 
         Dim lReturn As Long 
         
         lReturn = WSACleanup() 
         
         If lReturn <> 0 Then 
         MsgBox "Socket error " & Trim$(Str$(lReturn)) & " occurred in Cleanup " 
         End 
         End If 
         
         End Sub 
         
         Sub Form_Load() 
         
         SocketsInitialize 
         
         End Sub 
         
         Private Sub Form_Unload(Cancel As Integer) 
         
         SocketsCleanup 
         
         End Sub 
         
         Private Sub Command1_click() 
         Dim hostname As String * 256 
         Dim hostent_addr As Long 
         Dim host As HOSTENT 
         Dim hostip_addr As Long 
         Dim temp_ip_address() As Byte 
         Dim i As Integer 
         Dim ip_address As String 
         
         If gethostname(hostname, 256) = SOCKET_ERROR Then 
         MsgBox "Windows Sockets error " & Str(WSAGetLastError()) 
         Exit Sub 
         Else 
         hostname = Trim$(hostname) 
         End If 
         
         hostent_addr = gethostbyname(hostname) 
         
         If hostent_addr = 0 Then 
         MsgBox "Winsock.dll is not responding." 
         Exit Sub 
         End If 
         
         RtlMoveMemory host, hostent_addr, LenB(host) 
         RtlMoveMemory hostip_addr, host.hAddrList, 4 
         
         MsgBox hostname 
         
         'get all of the IP address if machine is multi-homed 
         
         Do 
         ReDim temp_ip_address(1 To host.hLength) 
         RtlMoveMemory temp_ip_address(1), hostip_addr, host.hLength 
         
         For i = 1 To host.hLength 
         ip_address = ip_address & temp_ip_address(i) & "." 
         Next 
         ip_address = Mid$(ip_address, 1, Len(ip_address) - 1) 
         
         MsgBox ip_address 
         
         ip_address = "" 
         host.hAddrList = host.hAddrList + LenB(host.hAddrList) 
         RtlMoveMemory hostip_addr, host.hAddrList, 4 
         Loop While (hostip_addr <> 0) 
         
         End Sub 
      

  3.   

    leoxue() 你所列示的是本机的计算机名和IP。不是动态的IP
      

  4.   

    你一定要这样做的话恐怕没有什么API能解决你的问题.
    因为你要做的东西不确定性太大.
    就算shanhe(TNT)说的跟踪的方式你可以通过调API来实现(当然,如果能实现你的问题也就解决了90%了),但你还必须考虑到上网服务器(网关)的问题,他如果装了ICMP包的回应或者用的是路由式ADSL时,你发出的跟踪包未必能返回你要的网关IP.
    建议你还是在服务器上做个程序会比较好,开个listen,你连上去获得他的所有IP.我可以肯定,你想在你本机调API实现,难度太大.
      

  5.   

    Private Type HOSTENT
       hName As Long
       hAliases As Long
       hAddrType As Integer
       hLen As Integer
       hAddrList As Long
    End TypePrivate Declare Function gethostbyname Lib "wsock32" (ByVal hostname As String) As Long
    Private Declare Sub CopyMemoryIP Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)
    Private Declare Function GetComputerNameA Lib "kernel32" (ByVal lpBuffer As String, nSize As Long) As Long
    Public Function GetIPFromHostName(ByVal sHostName As String) As String    Dim ptrHosent   As Long
        Dim Host        As HOSTENT
        Dim dwIPAddr    As Long
        Dim tmpIPAddr() As Byte
        Dim I           As Integer
        Dim sIPAddr     As String
        
       ptrHosent = gethostbyname(sHostName & vbNullChar)   If ptrHosent <> 0 Then
        
            CopyMemoryIP Host, ptrHosent, Len(Host)
            CopyMemoryIP dwIPAddr, Host.hAddrList, 4
            ReDim tmpIPAddr(1 To Host.hLen)
            CopyMemoryIP tmpIPAddr(1), dwIPAddr, Host.hLen
            For I = 1 To Host.hLen - 1
                sIPAddr = sIPAddr & tmpIPAddr(I) & "."
            Next
            sIPAddr = sIPAddr & tmpIPAddr(I)
            GetIPFromHostName = sIPAddr
            
       End If
       
    End FunctionPublic Function GetComputerName() As String
       Dim UserName As String * 255   Call GetComputerNameA(UserName, 255)
       GetComputerName = Left$(UserName, InStr(UserName, Chr$(0)) - 1)
    End Function===========================Private Sub Command1_Click()
        MsgBox GetComputerName & vbCrLf & GetIPFromHostName(GetComputerName)
    End Sub
    试一试!!!!
      

  6.   

    C:\>tracert 218.77.39.97Tracing route to 218.77.39.97 over a maximum of 30 hops  1   <10 ms   <10 ms   <10 ms  192.168.1.1
      2     *        *        *     Request timed out.
      3    60 ms    60 ms    70 ms  218.77.39.97Trace complete.C:\>