C#でINATExternalIPAddressCallbackとNATの外部たIPAddressを取得しようとしています

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

  •  18-09-2019
  •  | 
  •  

質問

私は、Windowsのライブラリを使用してNATの外部IPアドレスを取得するにはどうすればよいですか?私はINATExternalIPAddressCallback上の任意の情報を検索しようとしていますが、唯一のC#に利用できないインターフェースを使用してC ++に一例を発見しました。任意のガイダンスははるかに高く評価されるだろう。

-Karl

役に立ちましたか?

解決

申し訳ありませんが、私はUPnPサービスを使用するWindowsから既存のAPIと答えていませんが、それはあなたを助けるmighこと

また、インターネット上でSTUNサーバーを使用することができ、多くのオープンなものがあり、すべてのVOIPプロバイダーは、いずれかを持っています。 http://en.wikipedia.org/wiki/STUNする http://tools.ietf.org/html/rfc3489する

例えば。 UDPソケットを開いて、ポート3478でstun.gmx.netと、このようpaketを送信するために接続します:

using System;
using System.Net;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace xxx
{
class STUNPacket
{
    static RNGCryptoServiceProvider m_rand=new RNGCryptoServiceProvider();

    private byte[] m_requestid=new byte[16];

    public STUNPacket()
    {
        m_rand.GetBytes(m_requestid);
    }

    public byte[] CreateRequest()
    {
        byte[] packet=new byte[0x1c] {
            //Header:
            0x00,0x01,      //Art des STUN-Pakets: 0x0001=Binding Request
            0x00,0x08,      //Länge des Pakets ohne Header
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //Transkations-ID
            //Message-Attribute:
            0x00,0x03,      //Typ: Change-Request
            0x00,0x04,      //Länge: 4 Bytes
            0x00,0x00,0x00,0x00 //Weder IP, noch Port ändern
        };

        for(int i=0;i<16;i++)
            packet[i+4]=m_requestid[i];

        return packet;
    }

    public IPEndPoint ParseResponse(byte[] paket)
    {
        if (paket.Length<20)
            throw new Exception("STUN-Response zu kurz, um einen Header zu haben");
        if (paket[0]!=1||paket[1]!=1)
            throw new Exception("STUN-Reposne hat falschen Typ, muss Binding-Response sein");
        for (int i=0;i<16;i++)
            if (paket[i+4]!=m_requestid[i])
                throw new Exception("STUN-Antwort hat falsche Transkations-ID");
        int size=paket[2]*256+paket[3];
        int pos=20;
        for(;;)
        {
            if (size<4)
                throw new Exception("Verbleibende Nachricht zu kurz für weiteren Attributheader, "+
                    "Mapped-Adress-Attribut nicht gefunden");
            int attrsize=paket[pos+2]*256+paket[pos+3];
            if (pos+4+attrsize>paket.Length)
                throw new Exception("Attributheader hat Länge, die nicht mehr ins Paket passt");
            //Wenn kein Mapped-Adress-Attribut, dann überspringen
            if (paket[pos]!=0||paket[pos+1]!=1)
            {
                pos+=attrsize;
                continue;
            }
            if (attrsize<8)
                throw new Exception("Mapped-Adress-Attribut ist zu kurz");
            if (paket[pos+5]!=1)
                throw new Exception("Adreßfamilie von Mapped-Adress ist nicht IPV4");
            int port=paket[pos+6]*256+paket[pos+7];
            IPAddress adress=new IPAddress(new byte[4] { paket[pos+8],paket[pos+9],paket[pos+10],paket[pos+11] });
            return new IPEndPoint(adress,port);
        }
    }

}

}

外の世界はそれを見ているように、

ParseResponseによって返されたIPアドレスは、あなたのIPアドレスである必要があります。

サーバーからのUPnPを経由してインターネットサーバのヘルプまたは直接的にせずに自分の外部IPアドレスを取得することができなくなります

他のヒント

CodeProjectのではハロルドのaptrootによって次の記事では、あなたが何をしたいかを説明します:

の任意のライブラリのないC#でのUPnPとNATトラバーサル、。 http://www.codeproject.com/KB/IP/upnpnattraversal.aspx

お使いのルータがUPnPをサポートしている場合は、

オフもちろん、これはのみ動作します。

MSDNから - ます。http:// MSDN。 microsoft.com/en-us/library/aa365074(VS.85).aspxするます:

INATExternalIPAddressCallbackインタフェースは、UPnP技術とNATアプリケーションによって実装されます。これは、システムがNATコンピュータの外部IPアドレスの変更の場合は呼び出すメソッドを提供しています。

あなたは一度外部IPアドレスを取得しようとしているか、あなたはそれが変化した場合に通知されるようにしたいです。あなただけの現在の外部IPアドレスを取得したい場合は、INATExternalIPAddressCallbackのためのコールバックを実装する必要はありません。

NATの背後にあるシステムは、それはだ「本物」のIPを知りません。実際には、限りOSが懸念しているとして、それは他のどのようなIPを持っています。これは単に、定義されたゲートウェイへと出てルートが詳細を心配する必要はありません。 IPが設定されているという事実は、ブロードキャストアドレス(10.whatever、192.168.whatever)ではありませんOSには関係ありません。

あなたの外部IPを取得する唯一の方法は、いくつかの外部のシステムに照会することです。それは(、thoeryに、さらに別の非ブロードキャストアドレスを返すことができます)あなたのUPnPルータであるかもしれませんか、それが(例えば、この「STUN」のもの)、インターネット上のいくつかの外部サーバーかもしれません。

それは私だったら

、私はちょうど私のウェブサイト上で自分のサービスをホストすると思います。あなたは、ほとんどの任意のPHP対応のウェブサイト上で簡単なPHPスクリプトを投げることができます:

<?php echo $REMOTE_ADDR; >

これは、クライアントのIPアドレスをキックバックされます。次は(C#でかなり簡単)、そのスクリプトの結果をつかむために、クライアントのコードを書くようになってきました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top