Get external IP address over remoting in C#

前端 未结 12 1639
夕颜
夕颜 2020-12-05 05:16

I need to find out the external IP of the computer a C# application is running on.

In the application I have a connection (via .NET remoting) to a

相关标签:
12条回答
  • 2020-12-05 05:34

    Better to just use http://www.whatismyip.com/automation/n09230945.asp it only outputs the IP just for the automated lookups.

    If you want something that does not rely on someone else put up your own page http://www.unkwndesign.com/ip.php is just a quick script:

    <?php
    echo 'Your Public IP is: ' . $_SERVER['REMOTE_ADDR'];
    ?>
    

    The only downside here is that it will only retrieve the external IP of the interface that was used to create the request.

    0 讨论(0)
  • 2020-12-05 05:35

    Jonathan Holland's answer is fundamentally correct, but it's worth adding that the API calls behind Dns.GetHostByName are fairly time consuming and it's a good idea to cache the results so that the code only has to be called once.

    0 讨论(0)
  • 2020-12-05 05:38

    Dns.GetHostEntry(Dns.GetHostName()); will return an array of IP addresses. The first one should be the external IP, the rest will be the ones behind NAT.

    So:

    IPHostEntry IPHost = Dns.GetHostEntry(Dns.GetHostName());
    string externalIP = IPHost.AddressList[0].ToString();
    

    EDIT:

    There are reports that this does not work for some people. It does for me, but perhaps depending on your network configuration, it may not work.

    0 讨论(0)
  • 2020-12-05 05:39

    I believe theoretically you are unable to do such a thing while being behind a router (e.g. using invalid ip ranges) without using an external "help".

    0 讨论(0)
  • 2020-12-05 05:42

    I found a way that worked great for me. By implementing a custom IServerChannelSinkProvider and IServerChannelSink where I have access to CommonTransportKeys.IPAddress, it's easy to add the client ip on the CallContext.

    public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, 
        IMessage requestmessage, ITransportHeaders requestHeaders, 
        System.IO.Stream requestStream, out IMessage responseMessage, 
        out ITransportHeaders responseHeaders, out System.IO.Stream responseStream)
    {
        try
        {
            // Get the IP address and add it to the call context.
            IPAddress ipAddr = (IPAddress)requestHeaders[CommonTransportKeys.IPAddress];
            CallContext.SetData("ClientIP", ipAddr);
        }
        catch (Exception)
        {
        }
    
        sinkStack.Push(this, null);
        ServerProcessing srvProc = _NextSink.ProcessMessage(sinkStack, requestmessage, requestHeaders,
            requestStream, out responseMessage, out responseHeaders, out responseStream);
    
        return srvProc;
    }
    

    And then later (when I get a request from a client) just get the IP from the CallContext like this.

    public string GetClientIP()
    {
        // Get the client IP from the call context.
        object data = CallContext.GetData("ClientIP");
    
        // If the data is null or not a string, then return an empty string.
        if (data == null || !(data is IPAddress))
            return string.Empty;
    
        // Return the data as a string.
        return ((IPAddress)data).ToString();
    }
    

    I can now send the IP back to the client.

    0 讨论(0)
  • 2020-12-05 05:43

    The main issue is the public IP address is not necessarily correlated to the local computer running the application. It is translated from the internal network through the firewall. To truly obtain the public IP without interrogating the local network is to make a request to an internet page and return the result. If you do not want to use a publicly available WhatIsMyIP.com type site you can easily create one and host it yourself - preferably as a webservice so you can make a simple soap compliant call to it from within your application. You wouldn't necessarily do a screen capture as much as a behind the scenes post and read the response.

    0 讨论(0)
提交回复
热议问题