将数据发送到127. *:无法访问的主机

时间:2011-04-11 17:27:21

标签: c# networking windows-xp loopback

我正在尝试发送到在Windows XP上运行的.NET 3.5应用程序中的环回地址空间。代码很简单:

receiver = new IPEndPoint(IPAddress.Parse("127.0.0.2"), 8000);
sock.SendTo(data, len, SocketFlags.None, receiver);

当我运行代码时,我得到一个无法访问的主机套接字异常。这对我来说似乎很奇怪,因为环回接口始终存在,并且它不应该生成任何无法访问的主机异常。

Windows 7执行代码很好,使问题更加奇怪。

所以 - 如果有人有任何关于让它在XP中运行的技巧,我会很感激。

编辑:

一些信息:

  • 有些东西在127.0.0.2上收听,我的netstat显示:
  • UDP 127.0.0.2:8000 5824

  • 我正在运行XP SP3,我的测试机上没有防火墙

当我ping 127.0.0.2时,我注意到了XP,回复又回来了:

Reply from 127.0.0.1

在Windows 7上,回复来自我所说的地址:

Reply from 127.0.0.2

我认为这可能是问题,因此它不是一个真正的编程问题,它本身就是XP本身的问题......

- 丹

4 个答案:

答案 0 :(得分:1)

是否适用于127.0.0.1The RFC说:

  

127.0.0.0/8 - 此块已分配用作Internet主机      环回地址。由更高级别协议发送到的数据报      该块内的任何地址都应该在主机内部循环。      这通常只使用 127.0.0.1/32 进行环回,      但此块中的地址不应出现在任何网络上       [RFC1700,第5页]

这似乎表明你不应该依赖127.0.0.2工作,除非你专门设置了什么。

答案 1 :(得分:1)

我按照这篇文章的答案中提到的步骤解决了问题:

How do you create a virtual network interface on Windows?

问题的根本原因是我需要在两个程序之间发送数据:

  • 进程A:必须在端口1234上发送/接收(我无法更改/重构此内容)
  • 进程B:必须从进程A发送/接收,但必须使用不同的接口,因为最终必须使用端口1234.

由于我最初使用127. *地址块的计划在XP上无法正常工作,因此我选择了虚拟网络接口方法。我创建了两个虚拟网络接口:

  • 172.17.1.1/255.255.0.0(流程A)
  • 172.17.1.2/255.255.0.0(流程B)

172.17地址块已经用于其他东西,所以它在这里工作正常。不完全是我想要的,因为我必须在用户的PC上添加2个环回适配器 - 但它可以完成工作。

- 丹

答案 2 :(得分:0)

您是否有服务器在端口8000上侦听地址127.0.0.2(与localhost不同,尽管是环回)?如果没有,它将无法连接,因为没有任何收听。我怀疑你的Win7盒子上有什么东西在听。

netstat -b -n -a

应该告诉你什么。

修改

我怀疑你正在运行XP SP2:

http://support.microsoft.com/kb/884020(修复可用)

IIRC他们通过SP3删除了这个问题

答案 3 :(得分:0)

在Windows 8.0 x64上,问题似乎仍然存在,有时...... 我不知道,当问题存在时,如果不存在,它甚至会出现在新的启动Windows中... 我改变了我的程序,将“localhost”解释为其本地ip 4地址。


    public static IPAddress GetConfiguredIPAddress()
    {
        string serverIPString = System.Configuration.ConfigurationManager.AppSettings["serverIP"];

        if (serverIPString.ToLower() == "localhost")
        {
            System.Net.IPHostEntry localhost = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
            foreach (var item in localhost.AddressList)
            {
                if (item.AddressFamily == AddressFamily.InterNetwork && item.GetAddressBytes()[0] != 127)
                {
                    return item;   
                }
            }
        }

        IPAddress result = null;
        if (IPAddress.TryParse(serverIPString, out result))
        {
            return result;
        }

        //I experienced problems with Upper Case DNS Names, so i change this here.
        //dont know if thats correct, because if its really that issue, 
        //it would have been implemented in the Dns class.
        //Note: This also resolves localhost to 127.0.0.1 if you are not connected to any network.
        IPAddress[] dnsAddresses = System.Net.Dns. GetHostAddresses(serverIPString.ToLower());

        if (dnsAddresses.Length > 0)
        {
            IPAddress foundIP4 = null;
            IPAddress foundOtherAddress = null; //usally ipv6

            foreach (IPAddress ip in dnsAddresses)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    foundIP4 = ip;
                }
                else
                {
                    foundOtherAddress = ip;
                }

            }
            if (foundIP4 != null)
            {
                return foundIP4;
            }
            return foundOtherAddress;
        }

        throw new InvalidOperationException("Unable to get IPAddress for " + serverIPString);
    }