使用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
相关产品推荐
相关产品推荐

