试图让NAT外部ip地址与INATExternalIPAddressCallback在C# [英] Trying to get NAT's external IPAddress with INATExternalIPAddressCallback in C#

查看:159
本文介绍了试图让NAT外部ip地址与INATExternalIPAddressCallback在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何获得使用Windows库中的NAT的外部IP地址?我试图找到任何INATExternalIPAddressCallback信息,但只找到用C一个例子++使用不可用接口C#。任何指导,将不胜感激。

How do I get the external IP Address of a NAT using the windows library? I am trying to find any information on INATExternalIPAddressCallback, but have only found one example in C++ using unavailable interfaces to C#. Any guidance would be much appreciated.

-Karl

推荐答案

对不起,我不从Windows使用UPnP服务的现有API回答,但它migh帮助你。

Sorry, that I don't answer with an existing API from Windows that uses the UPNP service, but it migh help you

您也可以使用STUN服务器在互联网上也有很多开放的人,每一个VoIP服务提供商有一个。
http://en.wikipedia.org/wiki/STUN
http://tools.ietf.org/html/rfc3489

You could also use a STUN-server on the internet, there are many open ones, every VOIP provider has one. http://en.wikipedia.org/wiki/STUN http://tools.ietf.org/html/rfc3489

如打开一个UDP套接字,连接到stun.gmx.net端口3478和发送的一揽子贷款是这样的:

e.g. open an UDP-socket, connect to stun.gmx.net on port 3478 and send a paket like this:

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地址像外界看到它。

The IP-address returned by ParseResponse should be your ip adress like the outside world sees it.

注意,将不能够得到您的外部IP,无需使用互联网服务器的任何帮助,或直接通过UPnP从服务器

这篇关于试图让NAT外部ip地址与INATExternalIPAddressCallback在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆