Remoting获取客户端的外网IP地址

其实在服务端Remoting可以像读取一个变量一样来获取到连接过来的客户端的IP,不过这个IP不是太容易的取到。

网上有一个解决方案就是使用配置文件来吸取IP地址,但是这个方案需要我们使用配置文件来使用Remoting,如果我们是代码形式的程序,那么怎样获取客户端IP呢。

Remoting、WebService底层都是用Socket来实现,Socket本身很容易的可以获取到IP地址,所以理论上Remoting获取客户端IP是通过的。

我们可以从吸取器入手来获取,假如我们使用TCP通道来通信,在服务端使用TcpServerChannel类,该类其实已支持了吸取器,构造函数如下:

public TcpServerChannel(string name, int port, IServerChannelSinkProvider sinkProvider);

TcpServerChannel类默认的吸取器是BinaryServerFormatterSinkProvider,而吸取器可以设置链表上的下一个吸取器,然后依次执行每一个吸取器。

我们可以得到如下的代码:

IServerChannelSinkProvider serverSink = new ClientIPServerSinkProvider();
BinaryServerFormatterSinkProvider firstSink = new BinaryServerFormatterSinkProvider();
firstSink.Next = serverSink;
TcpServerChannel channel = new TcpServerChannel("tcpserver", port, firstSink);
ChannelServices.RegisterChannel(channel, true);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotableClass), "RemotableClass", WellKnownObjectMode.Singleton);

到这里,如果定义好了RemotableClass类,那么就可以直接取IP地址了:

	public class RemotableClass : MarshalByRefObject
	{
		protected string getIPAddress()
		{
			System.Net.IPAddress ip = System.Runtime.Remoting.Messaging.CallContext.GetData("ClientIPAddress") as System.Net.IPAddress;
			if (ip != null)
			{
				return ip.ToString();
			}
			return null;
		}
	}

如果不知道吸取器的代码,可以参考如下:

	public class ClientIPServerSinkProvider : IServerChannelSinkProvider
	{
		private IServerChannelSinkProvider next = null;

		public ClientIPServerSinkProvider()
		{
		}

		public ClientIPServerSinkProvider(IDictionary properties, ICollection providerData)
		{
		}

		public void GetChannelData(IChannelDataStore channelData)
		{
		}

		public IServerChannelSink CreateSink(IChannelReceiver channel)
		{
			IServerChannelSink nextSink = null;
			if (next != null)
			{
				nextSink = next.CreateSink(channel);
			}

			return new ClientIPServerSink(nextSink);
		}

		public IServerChannelSinkProvider Next
		{
			get { return next; }
			set { next = value; }
		}
	}
	public class ClientIPServerSink : BaseChannelObjectWithProperties, IServerChannelSink, IChannelSinkBase
	{
		private IServerChannelSink _next;

		public ClientIPServerSink(IServerChannelSink next)
		{
			_next = next;
		}

		public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers, Stream stream)
		{
		}

		public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers)
		{
			return null;
		}

		public System.Runtime.Remoting.Channels.ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
		{
			if (_next != null)
			{
				IPAddress ip = requestHeaders[CommonTransportKeys.IPAddress] as IPAddress;
				CallContext.SetData("ClientIPAddress", ip);
				return _next.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);
			}
			else
			{
				responseMsg = null;
				responseHeaders = null;
				responseStream = null;

				return ServerProcessing.Complete;
			}
		}

		public IServerChannelSink NextChannelSink
		{
			get
			{
				return _next;
			}
			set
			{
				_next = value;
			}
		}
	}

到这里就完成了。

时间: 2024-10-12 18:31:16

Remoting获取客户端的外网IP地址的相关文章

c#获取外网IP地址的方法

1.如果你是通过路由上网的,可以通过访问ip138之类的地址来获取外网IP 2.如果是通过PPPOE拨号上网的,可以使用以下代码获取IP //获取宽带连接(PPPOE拨号)的IP地址,timeout超时(秒),当宽带未连接或者连接中的时候获取不到IP public static string GetIP_PPPOE(int timeout) { int i = timeout * 2; while (i > 0) { try { NetworkInterface[] nics = Network

shell脚本,提取ip地址和子网掩码,和查外网ip地址信息。

#提取IP地址和子网掩码 [[email protected] ~]# ifconfig eth0|grep 'inet addr'|awk -F'[ :]+' '{print $4"/"$8}' 192.168.16.110/255.255.255.0 [[email protected] ~]# #查外网IP地址 [[email protected] ~]# curl -s ipecho.net/plain;echo 114.93.99.39 #查外网ip地址是什么宽带<br

外网IP地址 内网 IP

外网IP地址 大部分网络使用B类或C类地址,每一个类的第一个八位组的范围如下: 1.0-—127.A类 网络号码范围是 0.0.0.0---127.0.0.0 ,用于128个网络.但网络不能全由0组成且127.0.0.0保留用于回路.剩下的126个网络,1到126,共有16777214个可能的主机地址(16777216减2) A类 网络 —主机—主机—主机 0-127 127 0 0 0 2.128—191.B类,网络号码范围是128.0.0.0--191.254.0.0 用于16256个网络.

Windows Azure 设置虚拟机静态外网IP地址

官方说法叫做“虚拟公共IP地址保留”,为容易理解,我们称之为静态外网IP地址. 如果在国内使用国际版Windows Azure服务时强烈推荐为虚拟机设置IP地址保留. 由于Windows Azure Cloud Service的内部IP地址和虚拟公共IP地址(VIP)是非固定的,且不允许自行更改,很有可能会遇到被分配到一个在国内无法访问的IP地址(大墙V5).因此在能够正常访问时,设置保留此IP地址. 注:需要额外支付费用,定价信息请参考:http://azure.microsoft.com/e

H3C SecPath U200-S 如何在内网使用外网IP地址访问内网服务器

H3C SecPath U200-S 如何在内网使用外网IP地址访问内网服务器 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 这个问题很经典的,防火墙上显然配置了NAT的方式进行了转换,但是内部用户在访问的

MFC C++ 获取外网IP地址

#include <afxinet.h> //GB2312 转换成 Unicode wchar_t* GB2312ToUnicode(const char* szGBString) { UINT nCodePage = 936; //GB2312 int nLength=MultiByteToWideChar(nCodePage,0,szGBString,-1,NULL,0); wchar_t* pBuffer = new wchar_t[nLength+1]; MultiByteToWide

云服务器查看外网IP地址方法

#返回IP地址 curl ip.6655.com/ip.aspx curl whatismyip.akamai.com wget -qO - ifconfig.co curl icanhazip.com dig +short myip.opendns.com @resolver1.opendns.com curl ident.me curl v4.ident.me curl curlmyip.com curl ifconfig.me curl inet-ip.info #返回IP和地区 1.cu

查询某软件所连接的外网IP地址

一:背景环境: 1>:某机械公司用的某些特殊软件,需要实现所有使用某软件的屏蔽其软件所连接的外网ip,其他上网功能不做限制. 二:需求分析:可以查出此软件所连接的外网ip,在路由器的ip过滤中将其屏蔽,方可实现需求. 三:功能实现: 1> 来自微软官方软件: http://live.sysinternals.com/Tcpview.exe 2> 官网网页:https://docs.microsoft.com/zh-cn/sysinternals/  (参考) 3> 举例: 4>

.NET获取客户端的操作系统、IP地址、浏览器版本

#region 获取操作系统版本号 /// <summary> /// 获取操作系统版本号 /// </summary> /// <returns></returns> public static string GetOSVersion() { //UserAgent var userAgent = HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"]; var os