Получите внешний IP-адрес по дистанционной работе в C#

Вот один из способов, который я должен был использовать один или два раза:

public abstract class GenericClass<T>{
    public abstract Class<T> getMyType();
}

Наряду с

public class SpecificClass extends GenericClass<String>{

    @Override
    public Class<String> getMyType(){
        return String.class;
    }
}
20
задан Patrik Svensson 2 December 2008 в 23:43
поделиться

12 ответов

Я нашел способ, который отлично мне подходит. Реализуя настраиваемые IServerChannelSinkProvider и IServerChannelSink, где у меня есть доступ к CommonTransportKeys.IPAddress, легко добавить IP-адрес клиента в 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;
}

А потом (когда я получаю запрос от клиента) просто получаю IP из CallContext вот так.

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();
}

Теперь я могу отправить IP обратно клиенту.

5
ответ дан 29 November 2019 в 23:45
поделиться

DNS. GetHostEntry (DNS. GetHostName ()); возвратит массив IP-адресов. Первый должен быть внешним IP, остальные будут теми позади NAT.

Так:

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

РЕДАКТИРОВАНИЕ:

существуют отчеты, что это не работает на некоторых людей. Это делает для меня, но возможно в зависимости от Вашей конфигурации сети, это не может работать.

6
ответ дан 29 November 2019 в 23:45
поделиться

Это - один из тех вопросов, где необходимо выглядеть глубже и возможно заново продумать исходную проблему; в этом случае, "Почему Вам нужен внешний IP-адрес?"

проблема - то, что компьютер не может иметь внешнего IP-адреса. Например, моему ноутбуку присвоил внутренний IP-адрес (192.168.x.y) маршрутизатор. Сам маршрутизатор имеет внутренний IP-адрес, но его "внешний" IP-адрес является также внутренним. Это только используется для общения с модемом DSL, который на самом деле имеет внешний, стоящий с Интернетом IP-адрес.

, Таким образом, реальный вопрос становится, "Как я получаю стоящий с Интернетом IP-адрес устройства 2 транзитных участка далеко?" И ответ обычно, Вы не делаете; по крайней мере, не используя сервис, такой как whatismyip.com, который Вы уже отклонили, или выполнение действительно крупного взлома, включающего жесткое кодирование модемный пароль DSL в Ваше приложение и запрашивающего модем DSL и анализ экранных данных администраторская страница (и Бог помогают Вам, если модем когда-либо заменяется).

РЕДАКТИРОВАНИЕ: Теперь для применения этого к пересмотренному вопросу, "Как я получаю IP-адрес своего клиента с сервера компонент.NET?" Как whatismyip.com, лучшее, которое сервер сможет сделать, дают Вам IP-адрес Вашего стоящего с Интернетом устройства, которое вряд ли будет фактическим IP-адресом компьютера, запускающего приложение. Возвращение к моему ноутбуку, если бы мой стоящий с Интернетом IP был 75.75.75.75 и IP LAN, было 192.168.0.112, сервер только смог бы видеть 75.75.75.75 IP-адресов. Это получит его до моего модема DSL. Если бы Ваш сервер хотел установить отдельную связь назад с моим ноутбуком, то я должен был бы сначала настроить модем DSL и любой промежуток маршрутизаторов это и мой ноутбук, чтобы распознать входящие соединения с Вашего сервера и направить их соответственно. Существует несколько способов сделать это, но это выходит за рамки этой темы.

, Если Вы на самом деле пытаетесь установить связь из сервера назад клиенту, заново продумайте свой дизайн, потому что Вы копаетесь в территории WTF (или по крайней мере, подавая Вашу заявку что намного тяжелее развернуться).

19
ответ дан 29 November 2019 в 23:45
поделиться

Лучше, чтобы просто использовать http://www.whatismyip.com/automation/n09230945.asp это только производит IP только для автоматизированных поисков.

Если Вы хотите что-то, что не полагается на кого-то еще, поднял Вашу собственную страницу http://www.unkwndesign.com/ip.php, просто быстрый сценарий:

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

Единственный недостаток здесь - то, что это только получит внешний IP интерфейса, который использовался для создания запроса.

5
ответ дан 29 November 2019 в 23:45
поделиться

Ответ Jonathan Holland существенно корректен, но стоит добавить что вызовы API позади DNS. GetHostByName являются довольно трудоемкими, и это - хорошая идея кэшировать результаты так, чтобы код только назвали однажды.

4
ответ дан 29 November 2019 в 23:45
поделиться

Основным вопросом является общедоступный IP-адрес, не обязательно коррелируется к локальному компьютеру, запускающему приложение. Это переводится с внутренней сети на брандмауэр. Действительно получить общедоступный IP, не опрашивая локальную сеть означает выполнить запрос к интернет-странице и возвратить результат. Если Вы не хотите использовать общедоступный сайт типа WhatIsMyIP.com, можно легко создать один и разместить его сами - предпочтительно как веб-сервис, таким образом, можно сделать простое мыло совместимым вызовом к нему из приложения. Вы не обязательно сделали бы снимок экрана так же как негласно сообщение и считали бы ответ.

3
ответ дан 29 November 2019 в 23:45
поделиться

Если Вы просто хотите IP, это связывается с адаптером, можно использовать WMI и класс Win32_NetworkAdapterConfiguration.

http://msdn.microsoft.com/en-us/library/aa394217 (По сравнению с 85) .aspx

2
ответ дан 29 November 2019 в 23:45
поделиться

Ну, принятие Вас имеет System.Net.Sockets.TcpClient подключенный к Вашему клиенту, Вы можете (на сервере) использование client.Client.RemoteEndPoint. Это даст Вам System.Net.EndPoint указывающий на клиент; то, что должен содержать экземпляр эти System.Net.IPEndPoint подкласс, хотя я не уверен в условиях для этого. После кастинга, к которому, можно проверить, что это Address свойство для получения адреса клиента.

Короче говоря, мы имеем

using (System.Net.Sockets.TcpClient client = whatever) {
    System.Net.EndPoint ep = client.Client.RemoteEndPoint;
    System.Net.IPEndPoint ip = (System.Net.IPEndPoint)ep;
    DoSomethingWith(ip.Address);
}

Удача.

1
ответ дан 29 November 2019 в 23:45
поделиться

Я верю теоретически, что Вы не можете сделать такую вещь будучи позади маршрутизатора (например, использование недопустимых диапазонов IP), не используя внешнюю "справку".

0
ответ дан 29 November 2019 в 23:45
поделиться

Можно в основном проанализировать страницу, возвращенную путем выполнения WebRequest http://whatismyipaddress.com

http://www.dreamincode.net/forums/showtopic24692.htm

-2
ответ дан 29 November 2019 в 23:45
поделиться

Самый надежный способ выполнения этого проверяет сайт как http://checkip.dyndns.org/ или подобный, потому что, пока Вы на самом деле не переходите внешние к своей сети, Вы не можете найти свой внешний IP. Однако жесткое кодирование такой URL просит возможный отказ. Можно хотеть только выполнить эту проверку, если текущий IP похож RFC1918 частный адрес (192.168.x.x являющийся самым знакомым из них.

Сбой, что, можно реализовать собственное, подобное, сервис, находящийся внешний к брандмауэру, таким образом, Вы будете, по крайней мере, знать, повреждается ли он.

-3
ответ дан 29 November 2019 в 23:45
поделиться

Patrik's solution works for me!

I made one important change. In process message I set the CallContext using this code:

// try to set the call context
LogicalCallContext lcc = (LogicalCallContext)requestMessage.Properties["__CallContext"];
if (lcc != null)
{
    lcc.SetData("ClientIP", ipAddr);
}

This places the ip address in the correct CallContext, so it can later be retrieved with GetClientIP () .

2
ответ дан 29 November 2019 в 23:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: