احصل على عنوان IP خارجي عبر التحكم عن بعد في C#

StackOverflow https://stackoverflow.com/questions/66363

  •  09-06-2019
  •  | 
  •  

سؤال

أنا بحاجة لمعرفة خارجي IP الخاص بالكمبيوتر الذي يعمل عليه تطبيق C#.

في التطبيق لدي اتصال (عبر .NET عن بعد) بالخادم.هل هناك طريقة جيدة للحصول على عنوان العميل من جانب الخادم؟

(لقد قمت بتحرير السؤال ليكون أكثر وضوحًا.أعتذر لجميع الأشخاص الطيبين الذين بذلوا قصارى جهدهم للرد على السؤال، عندما كنت غامضًا بعض الشيء)

حل:
لقد وجدت طريقة عملت بشكل رائع بالنسبة لي.من خلال تنفيذ 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

لقد وجدت طريقة عملت بشكل رائع بالنسبة لي.من خلال تنفيذ 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 مرة أخرى إلى العميل.

نصائح أخرى

هذا أحد الأسئلة التي يتعين عليك فيها النظر بشكل أعمق وربما إعادة التفكير في المشكلة الأصلية؛في هذه الحالة، "لماذا تحتاج إلى عنوان 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 للشبكة المحلية هو 192.168.0.112، فلن يتمكن الخادم إلا من رؤية عنوان IP 75.75.75.75.سيؤدي ذلك إلى وصوله إلى مودم DSL الخاص بي.إذا أراد الخادم الخاص بك إجراء اتصال منفصل مرة أخرى بالكمبيوتر المحمول الخاص بي، فسأحتاج أولاً إلى تكوين مودم DSL وأي أجهزة توجيه بينهما وبين الكمبيوتر المحمول الخاص بي للتعرف على الاتصالات الواردة من الخادم الخاص بك وتوجيهها بشكل مناسب.هناك عدة طرق للقيام بذلك، ولكنها خارج نطاق هذا الموضوع.

إذا كنت في الواقع تحاول إجراء اتصال من الخادم مرة أخرى إلى العميل، فأعد التفكير في تصميمك لأنك تتعمق في منطقة WTF (أو على الأقل، تجعل نشر تطبيقك أكثر صعوبة).

Dns.GetHostEntry(Dns.GetHostName());سيعود مجموعة من عناوين IP.الأول يجب أن يكون عنوان IP الخارجي، والباقي سيكون عنوان NAT.

لذا:

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

يحرر:

هناك تقارير تفيد بأن هذا لا يعمل بالنسبة لبعض الناس.إنه يعمل بالنسبة لي، ولكن ربما اعتمادًا على تكوين الشبكة لديك، قد لا يعمل.

من الأفضل أن تستخدم فقط http://www.whatismyip.com/automation/n09230945.asp فهو يقوم فقط بإخراج عنوان IP لعمليات البحث الآلية فقط.

إذا كنت تريد شيئًا لا يعتمد على شخص آخر، قم بوضع صفحتك الخاصة http://www.unkwndesign.com/ip.php هو مجرد نص سريع:

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

الجانب السلبي الوحيد هنا هو أنه لن يقوم سوى باسترداد عنوان IP الخارجي للواجهة التي تم استخدامها لإنشاء الطلب.

إجابة جوناثان هولاند صحيحة بشكل أساسي، ولكن تجدر الإشارة إلى أن استدعاءات واجهة برمجة التطبيقات (API) خلف Dns.GetHostByName تستغرق وقتًا طويلاً إلى حد ما، ومن الجيد تخزين النتائج مؤقتًا بحيث يتم استدعاء الكود مرة واحدة فقط.

المشكلة الرئيسية هي أن عنوان IP العام لا يرتبط بالضرورة بالكمبيوتر المحلي الذي يقوم بتشغيل التطبيق.تتم ترجمته من الشبكة الداخلية من خلال جدار الحماية.للحصول حقًا على عنوان IP العام دون استجواب الشبكة المحلية، يعني ذلك تقديم طلب إلى صفحة إنترنت وإرجاع النتيجة.إذا كنت لا ترغب في استخدام موقع من نوع WhatIsMyIP.com متاح للعامة، فيمكنك بسهولة إنشاء موقع واستضافته بنفسك - ويفضل أن يكون ذلك كخدمة ويب حتى تتمكن من إجراء مكالمة بسيطة متوافقة مع الصابون من داخل التطبيق الخاص بك.لن تقوم بالضرورة بالتقاط الشاشة بقدر ما تقوم بالنشر خلف الكواليس وقراءة الرد.

إذا كنت تريد فقط عنوان IP المرتبط بالمحول، فيمكنك استخدام WMI وفئة Win32_NetworkAdapterConfiguration.

http://msdn.microsoft.com/en-us/library/aa394217(VS.85).aspx

حل باتريك يناسبني!

لقد صنعت واحد تغيير مهم.في رسالة العملية قمت بتعيين CallContext باستخدام هذا الرمز:

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

يؤدي هذا إلى وضع عنوان IP في CallContext الصحيح، بحيث يمكن استرداده لاحقًاGetClientIP().

حسنًا، على افتراض أن لديك 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);
}

حظ سعيد.

أعتقد نظريًا أنك غير قادر على القيام بشيء كهذا أثناء تواجدك خلف جهاز التوجيه (على سبيل المثال.باستخدام نطاقات IP غير صالحة) دون استخدام "مساعدة" خارجية.

يمكنك بشكل أساسي تحليل الصفحة التي يتم إرجاعها عن طريق إجراء WebRequest http://whatismyipaddress.com

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

الطريقة الأكثر موثوقية للقيام بذلك هي التحقق من موقع مثل http://checkip.dyndns.org/ أو ما شابه ذلك، لأنه حتى تنتقل فعليًا إلى خارج شبكتك، لن تتمكن من العثور على عنوان IP الخارجي الخاص بك.ومع ذلك، فإن التشفير الثابت لعنوان URL هذا يتطلب فشلًا نهائيًا.قد ترغب في إجراء هذا الفحص فقط إذا كان عنوان IP الحالي يبدو كـ RFC1918 العنوان الخاص (192.168.x.x كونها الأكثر شهرة من هؤلاء.

إذا فشل ذلك، يمكنك تنفيذ الخدمة المشابهة الخاصة بك خارج جدار الحماية، لذلك ستعرف على الأقل ما إذا كانت معطلة أم لا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top