当前位置: 首页 > 编程语言 > C#

在C#中通过Remoting获取外部IP地址

时间:2023-04-11 02:02:27 C#

在C#中通过Remoting获取外部IP地址我需要找出运行C#应用程序的计算机的外部IP。在应用程序中,我有一个到服务器的连接(通过.NET远程处理)。有没有好的方法可以在服务器端获取客户端的地址?(我已经将问题编辑得更清楚了。我向所有尽力回答这个问题的人道歉,当时我可能有点太含糊了)解决方案:我找到了一种对我有用的方法.通过实现自定义IServerChannelSinkProvider和IServerChannelSink可以很容易地在CallContext上添加客户端ip,我可以在其中访问CommonTransportKeys.IPAddress。publicServerProcessingProcessMessage(IServerChannelSinkStacksinkStack,IMessagerequestmessage,ITransportHeadersrequestHeaders,System.IO.StreamrequestStream,outIMessageresponseMessage,outITransportHeadersresponseHeaders,outSystem.IO.addStreamresponseAddStream){//获取调用上下文.IPAddressipAddr=(IPAddress)requestHeaders[CommonTransportKeys.IPAddress];CallContext.SetData("ClientIP",ipAddr);}catch(Exception){}sinkStack.Push(this,null);ServerProcessingsrvProc=_NextSink.ProcessMessage(sinkStack,requestmessage,requestHeaders,requestStream,outresponseMessage,outresponseHeaders,outresponseStream);返回srvProc;然后(当我收到来自客户端的请求时)就像这样从CallContext获取IP。publicstringGetClientIP(){//从调用上下文中获取客户端IP。对象数据=CallContext。GetData("客户端IP");//如果数据为空或不是字符串,则返回空字符串。if(data==null||!(dataisIPAddress))returnstring.Empty;//以字符串形式返回数据。返回((IPAddress)data).ToString();我现在可以将IP发送回客户端。这是您需要更深入地挖掘并重新思考原始问题的问题之一;在这种情况下,“为什么需要外部IP地址?”问题是计算机可能没有外部IP地址。例如,我的笔记本电脑有一个由路由器分配的内部IP地址(192.168.xy)。路由器本身有一个内部IP地址,但它的“外部”IP地址也是内部的。它仅用于与DSL调制解调器通信,DSL调制解调器实际上有一个面向Internet的外部IP地址。所以,真正的问题是,“如何让我的设备面向Internet的IP地址跳到第2跳?”答案通常是,你不知道;至少不要使用像whatismyip.com这样你已经解雇的服务,或者做一个非常大的黑客攻击,包括将DSL调制解调器密码硬编码到你的应用程序中,查询DSL调制解调器和屏幕抓取管理页面(上帝帮助你,如果调制解调器已更换)。编辑:现在将其应用于重构的问题,“如何从服务器.NET组件获取客户端的IP地址?”与whatismyip.com一样,服务器最多只能为您提供面向Internet的设备,这不太可能是运行该应用程序的计算机的实际IP地址。回到我的笔记本电脑上,如果我面向互联网的IP是75.75.75.75而我的局域网IP是192.168.0.112,那么服务器只会看到75.75.75.75的IP地址。这将是我的DSL调制解调器。如果您的服务器想要单独连接到我的笔记本电脑,我首先需要配置DSL调制解调器和它与我的笔记本电脑之间的任何路由器,以识别来自服务器的传入连接并适当地路由它们。有多种方法可以执行此操作,但这超出了本主题的范围。如果您实际上正在尝试从服务器连接到客户端,请重新考虑您的设计,因为您正在深入WTF领域(或者至少,使您的应用程序更难部署)。Dns.GetHostEntry(Dns.GetHostName());将返回一个IP地址数组。第一个应该是外部IP,其余的将是NAT后面的IP。所以:IPHostEntryIPHost=Dns.GetHostEntry(Dns.GetHostName());字符串externalIP=IPHost.AddressList[0].ToString();编辑:据报道,这对某些人不起作用。它对我有用,但可能取决于您的网络配置,它可能不起作用。最好只使用http://www.whatismyip.com/automation/n09230945.asp它只是输出用于自动查找的IP。如果你想要一些不依赖于其他人的东西,你自己的页面http://www.unkwndesign.com/ip.php只是一个快速脚本:这里唯一的缺点是它只会检索用于创建请求IP。JonathanHolland的回答基本正确,但值得补充的是,Dns.GetHostByName背后的API调用比较耗时,最好缓存结果,这样代码只需要调用一次。我找到了一种适合我的方法。通过实现自定义IServerChannelSinkProvider和IServerChannelSink可以很容易地在CallContext上添加客户端ip,我可以在其中访问CommonTransportKeys.IPAddress。publicServerProcessingProcessMessage(IServerChannelSinkStacksinkStack,IMessagerequestmessage,ITransportHeadersrequestHeaders,System.IO.StreamrequestStream,outIMessageresponseMessage,outITransportHeadersresponseHeaders,outSystem.IO.addStreamresponseAddStream){//获取调用上下文.IPAddressipAddr=(IPAddress)requestHeaders[CommonTransportKeys.IPAddress];CallContext.SetData("ClientIP",ipAddr);}catch(Exception){}sinkStack.Push(this,null);ServerProcessingsrvProc=_NextSink.ProcessMessage(sinkStack,requestmessage,requestHeaders,requestStream,outresponseMessage,outresponseHeaders,outresponseStream);返回srvProc;然后(当我收到来自客户端的请求时)就像这样从CallContext获取IP。publicstringGetClientIP(){//从调用上下文中获取客户端IP。对象数据=CallContext。GetData("客户端IP");//如果数据为空或不是字符串,则返回空字符串。if(data==null||!(dataisIPAddress))returnstring.Empty;//以字符串形式返回数据。返回((IPAddress)data).ToString();我现在可以将IP发送回客户端。主要问题是公共IP地址不一定与运行应用程序的本地计算机相关联。它是通过防火墙从内部网络翻译过来的。在不询问本地网络的情况下实际获取公共IP是向互联网页面发出请求并返回结果。如果您不想使用公共WhatIsMyIP.com类型的站点,您可以轻松地创建一个并自己托管它-最好是作为Web服务,这样您就可以从您的应用程序中对其进行简单的SOAP兼容调用。您不一定像在幕后那样发布屏幕截图和阅读回复。如果您只想将IP绑定到适配器,则可以使用WMI和Win32_NetworkAdapterConfiguration类。http://msdn.microsoft.com/en-us/library/aa394217(VS.85).aspxPatrik的解决方案对我有用!我做了一个重要的改变。在进程消息中,我使用以下代码设置CallContext://尝试设置调用上下文LogicalCallContextlcc=(LogicalCallContext)requestMessage.Properties["__CallContext"];如果(lcc!=null){lcc.SetData("ClientIP",ipAddr);这会将ip地址放在正确的CallContext中,以便稍后可以使用GetClientIP()检索它。嗯,假设您有一个System.Net.Sockets.TcpClient连接到您的客户端,您可以(在服务器上)使用client.Client.RemoteEndPoint。这将为您提供一个指向客户端的System.Net.EndPoint;它应该包含一个System.Net.IPEndPoint子类的实例,尽管我不确定它的条件。转换为后,可以查看其Address属性,获取客户端的地址。总之,我们使用(System.Net.Sockets.TcpClientclient=whatever){System.Net.EndPointep=client.Client.RemoteEndPoint;System.Net.IPEndPointip=(System.Net.IPEndPoint)ep;DoSomethingWith(ip.Address);}祝你好运。我相信从理论上讲,当您在路由器后面时(例如使用无效的IP范围),如果不使用外部“帮助”,您将无法执行此类操作。您基本上可以通过对http://whatismyipaddress.com执行WebRequest来解析返回的页面http://www.dreamincode.net/forums/showtopic24692.htm最可靠的方法是检查http://checkip.dyndns.org/etc,因为在你真正离开网络之前,你无法找到外部IP。但是,硬编码这样的URL最终会导致失败。如果当前IP看起来像RFC1918私有地址(192.168.xx是其中最熟悉的),您可能希望只执行此检查。如果做不到这一点,您可以在防火墙外实施您自己的类似服务,这样您至少可以知道它是否已损坏。以上就是C#学习教程:在C#中通过远程处理获取外部IP地址共享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收集,不代表作品如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处: