You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C#确定Windows Server双IP场景下邮件发送的出口IP地址

问题描述

我的服务器操作系统为Windows Server 2008,配备两个网卡对应两个可用IP地址。
该服务器使用C# ASPNET和System.Net.Mail定时发送邮件,我需要确定邮件实际发送时使用的是两个可用IP中的哪一个。
我尝试使用下方代码查询,但仅能获取到两个IP中的第一个,而执行ping myserver命令返回的是第二个IP,请问有什么解决方法?

string hostName = Dns.GetHostName();
string myIP = Dns.GetHostByName(hostName).AddressList[0].ToString();
Response.Write(myIP.ToString());

【更新内容#01】我找到了一段路由接口查询的代码如下:

private static IPEndPoint QueryRoutingInterface(
          Socket socket,
          IPEndPoint remoteEndPoint)
{
    SocketAddress address = remoteEndPoint.Serialize();

    byte[] remoteAddrBytes = new byte[address.Size];
    for (int i = 0; i < address.Size; i++)
    {
        remoteAddrBytes[i] = address[i];
    }

    byte[] outBytes = new byte[remoteAddrBytes.Length];
    socket.IOControl(
                IOControlCode.RoutingInterfaceQuery,
                remoteAddrBytes,
                outBytes);
    for (int i = 0; i < address.Size; i++)
    {
        address[i] = outBytes[i];
    }

    EndPoint ep = remoteEndPoint.Create(address);
    return (IPEndPoint)ep;
}

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        IPAddress remoteIp = IPAddress.Parse("192.168.1.55");
        IPEndPoint remoteEndPoint = new IPEndPoint(remoteIp, 0);
        Socket socket = new Socket(
                              AddressFamily.InterNetwork,
                              SocketType.Dgram,
                              ProtocolType.Udp);
        IPEndPoint localEndPoint = QueryRoutingInterface(socket, remoteEndPoint);
        Console.WriteLine("Local EndPoint is: {0}", localEndPoint);
    }
}
解决方案

问题根源

你最初使用Dns.GetHostByName获取IP的方法本身就不适用于查询出站连接的实际IP:该方法返回的地址列表顺序由DNS解析规则决定,和系统路由决策的出站IP没有直接关联。ping 本机名返回的是系统默认出站IP,但发送邮件的IP由你连接的SMTP服务器地址对应的路由规则决定,两者可能存在差异。

代码修正

你更新的QueryRoutingInterface方法逻辑是完全正确的,本质是调用Windows系统的路由查询接口,直接获取连接指定远程地址时使用的本地出站IP,这个结果就是你发邮件时实际使用的IP,因为SMTP连接和路由查询的出站规则是一致的,不需要额外调整核心逻辑。

注意事项

  • 你提供的示例代码中IpEndPoint存在大小写拼写错误,需要修正为IPEndPoint才能正常编译。
  • 将代码中示例的远程IP"192.168.1.55"替换为你实际发邮件使用的SMTP服务器的IP地址,查询结果才有效。
  • 运行这段代码的ASP.NET进程身份需要拥有Socket操作权限,Windows Server 2008下默认的NETWORK SERVICE身份可正常调用,如果你自定义了运行身份需要确认权限配置。
  • 如果需要手动验证结果,可以在服务器命令行执行tracert 你的SMTP服务器IP,返回的第一跳源IP就是实际出站IP,可和代码查询结果对比确认。
  • Dns.GetHostByName已经在.NET Framework 2.0后被标记为过时,日常DNS查询推荐使用Dns.GetHostEntry方法,但该方法依然不适用出站IP查询场景。

内容的提问来源于stack exchange,提问作者Edward Sheriff Curtis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 20:30:00