惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
TaoSecurity Blog
TaoSecurity Blog
H
Heimdal Security Blog
Help Net Security
Help Net Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Microsoft Azure Blog
Microsoft Azure Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Google DeepMind News
Google DeepMind News
爱范儿
爱范儿
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
N
News | PayPal Newsroom
V2EX - 技术
V2EX - 技术
博客园 - 【当耐特】
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Secure Thoughts
C
CERT Recently Published Vulnerability Notes
罗磊的独立博客
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
有赞技术团队
有赞技术团队
S
Schneier on Security
S
SegmentFault 最新的问题
Google Online Security Blog
Google Online Security Blog
H
Hacker News: Front Page
The Last Watchdog
The Last Watchdog
Schneier on Security
Schneier on Security
PCI Perspectives
PCI Perspectives
IT之家
IT之家
Project Zero
Project Zero
博客园 - 司徒正美
P
Privacy International News Feed
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Jina AI
Jina AI
Security Latest
Security Latest
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
C
CXSECURITY Database RSS Feed - CXSecurity.com
阮一峰的网络日志
阮一峰的网络日志
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
V
Vulnerabilities – Threatpost
W
WeLiveSecurity
NISL@THU
NISL@THU
Webroot Blog
Webroot Blog
N
Netflix TechBlog - Medium
L
Lohrmann on Cybersecurity

博客园 - yellowyu

驴家网www.lvjia.cn全站全静态,其实技术在于活学活用 5年程序员流水帐总结,从开发到产品过渡 过滤HTML标签的几个函数 解决WCF传输大数据量时出错 使用InternetSetCookie 从System.Environment.TickCount 看最大支持,机子开一开还是要重启一下的 JScript 中Date.getTime转.Net中的DateTime 转:关系数据库中关系模式的规范过程 个人宣传画 我的身体已不再属于我 每一条路都是坚辛的,从未有平坦的 程序员与白咖啡,一种心情 真实故事:我的女友 今天做了淘宝客了。。。呵呵 暂时离开!=不再CODE .NET 中的对象序列化(转) Remoting :关于广域网事件回调失败与值传递 Winform:关于IM好友列表 Remoting(转)
Remoting: 如何穿越防火墙 (转)
yellowyu · 2009-08-14 · via 博客园 - yellowyu

试了之后还是不成功...但后一种办法还没试,标志一下...

Remoting 如何穿越防火墙

转自:http://blog.csdn.net/yj39867/archive/2004/08/03/60117.aspx

http://www.glacialcomponents.com/ArticleDetail.aspx?articleID=CAOMN

(翻译中...)

Introduction
"When I create a CAO from inside my network/router, everything works fine.? However, when I have a client outside my network that creates a CAO inside the network, it fails the first time I call a function.? What am I doing wrong!?!?!"

“在内部网中,我产生一个客户端激活对象(CAO),所有的都很正常。当我的客户端位于外部网,我调用远程对象的方法时,我得到了一个失败的结果,我错在什么地方?”

I hear this question on newsgroups and bulletin boards almost every day. The answer is actually pretty straightforward although it can get deeper if you wish to spice up the functionality.

我几乎每天经常听到这样的问题,如果你只想解决问题的话,答案非常简单;当然,你可以试着探索别后的机制,你将发现那很有趣。

Why this happens

When a CAO is created the server returns a URI that points to the unique instance of the CAO on the server.?This is how the server knows the unique instance you are using. (This is also why its very difficult to load balance CAO objects).The URI that the server sends back contains either the IP that it thinks it is or the IP you tell it that it really is.

当服务器产生CAO时同时也产生了一个URI,服务器根据这个URI标示远程客户端使用的对象实例。URI中包含了服务器实际IP的信息。(如果服务器位于内部网,实际上这个IP是一个内部IP,这是问题的根源)

How to fix it (the quick fix)

The simple fix for this that will work on most setups is to set the 'machineName' property of the channel on the server to the EXTERNAL ip that the client sees. This allows the server to return the external ip instead of its local internal IP. Typically you want to set the machineName equal to the EXTERNAL ip. This is the IP that your firewall or router has. This is also the IP that machines will see from outside your LAN when they go to connect to your remote object.

快速修正

最简单的修正办法就是设置通道的'machineName'属性为外部IP地址;这样,服务器返回给客户端的地址将是外部IP地址;

你可以用代码完成设置工作。(注:可以修改配置文件)

For example, for a TcpChannel you would do the following on the SERVER side of your code.

 IDictionary prop = new Hashtable();
 prop["port"] = 4000;
 prop["machineName"] = "myexternalip.com";
 tcpChannel = new TcpChannel(prop, null, null);
 ChannelServices.RegisterChannel(tcpChannel); 



That's all you need.?Your server should now work perfectly from outside your LAN/Firewall/Router.

There is a second method of fixing this problem which is much more complete, yet more complicated

A complete solution

What do I do if I need to access the server from both inside the LAN and outside without having to set machine name. Or what if I don't know what the machineName will be and I don't want to bother my users with having to know something mildly technical like that The machineName fix is ok, but it leaves a lot to be desired in many situations. This can be a real problem if its for a home or small business application where you may or may not have someone with a clue. Wouldn't it be easier if we just had a solution that worked everywhere Well your in luck!Because thats exactly what this is. This solution uses the IP that the CLIENT sees the server as (which you of course know or the client wouldn't be able to even connect to the server in the first place.

如果我不想设置“ machine name”属性,我该如何做?有很多原因使得我有这样的要求,例如,我可能不知道路由器的IP。既然客户端知道服务器的IP,我们是否可以利用这个IP,替换前面那种属性设置方案呢?

This solution also works very well where you have a multi-homed server (common in corporate intranets). A server with multiple NIC cards may be seen by many IPs each requiring a different route in and out of the server.This will work perfectly for that situation as well.

So how do I create a CAO on a server and have it work regardless if I'm inside or outside the local network。The answer lies in a rarely used class called the TrackingHandler. The basic process is as follows. We create our SAO Class Factory first, then when we go to create our CAO, we send the IP the client sees the server as in the creation call. This then puts the information in the CallContext where the tracking handler picks it up when it is fired during CAO creation and return.The tracking handler takes the URI that is being returned and replaces the server address with the address you have told the server you see it as. From then on, your CAO will work flawlessly against the server, you never have to do another thing.

解决办法是使用TrackingHandler,这是个很少使用的类。基本过程是这样,在产生CAO对象之前,我们将IP的信息传到CallContext中(调用环境),然后通过 tracking handler 来获取IP信息,并且用它来处理URI。



Now that I've given you the overview, lets get into the details.

First, this approach assumes that you are using a simple factory pattern to create your CAO.? You can see an explanation of factory pattern CAO creation in my article here.? This will also work if you use interfaces instead of abstract classes but for the purposes of this article we will focus on abstract class share type.

The factory create method for your CAO should accept a string.? This string will hold the address the client sees the server as.? Define it first in the abstract class then implement it in your SAO factory implementation.? I included a regular factory implementation along with the address based one so you can see both approaches.

// share.dll abstract SAO factory 
namespace ShareDLL 
{ 
public abstract class SAOCAOClassFactoryDef : MarshalByRefObject 
{
 public abstract CAOClassDef CreateCAOClass(); 
public abstract CAOClassDef CreateCAOClass( string strIP ); 
} 
} 
// implementation SAOCAOClassFactory.cs 
public class SAOCAOClassFactory : ShareDLL.SAOCAOClassFactoryDef
 { 
public override CAOClassDef CreateCAOClass() 
{ 
// this is important to clear out or it will get the address you left in on a previous factory c
 CallContext.FreeNamedDataSlot( "ObservedIP" ); 
return new CAOClass();
 // class factory create 
}
 public override CAOClassDef CreateCAOClass( string strAddress ) 
{
 CallContext.SetData("ObservedIP", strAddress);
 return new CAOClass();
 // class factory create
 } 
} 

Now that we have the address in the call context we can implement our tracking handler.?

Our tracking handler will grab the address out of the call context and insert it into the URI.

// trackinghandler.cs in server.exe 
public class ExampleTrackingHandler : ITrackingHandler
 {
 // Notify a handler that an object has been marshaled. 
public void MarshaledObject(Object obj, ObjRef or) 
{ // Assumption: We have a server channel sink that sets a call context flag
 // called "ObservedIP" whenever we are processing a remote request object 
ObservedIP = CallContext.GetData("ObservedIP");
 // for local clients we don't do anything here 
// if they don't specify the remote IP then we just use the servers IP 
if (ObservedIP == null)
 return;
 if (or.ChannelInfo == null)
 return; 
string strAddress = (string)ObservedIP;
 for ( int i = or.ChannelInfo.ChannelData.GetLowerBound(0);
 i <= or.ChannelInfo.ChannelData.GetUpperBound(0); i++ )
 {
 // Check for the ChannelDataStore object that we don't want to copy 
if(or.ChannelInfo.ChannelData[i] is ChannelDataStore)
 {
 // Personally I don't know why ChannelURIs is an array... I am only 
// familiar with there being one URI in each ChannelDataStore object
 foreach(string uri in ((ChannelDataStore)or.ChannelInfo.ChannelData[i]).ChannelUris)
 { // this will get the first part of the uri
 int nOffset = uri.IndexOf( "//" ) + 2; 
string strNewUri = uri.Substring( 0, nOffset ); 
strNewUri += strAddress; nOffset = uri.IndexOf( ":", nOffset );
 strNewUri += uri.Substring( nOffset, uri.Length - nOffset ); 
string[] strarray = new string[1] { strNewUri };
 ChannelDataStore cds = new ChannelDataStore( strarray ); 
or.ChannelInfo.ChannelData[i] = cds; } } } } } 

We have our class factory and our tracking handler, the last thing we need to do is make sure we register our tracking handler during the registration in our server. We do that with the simple RegisterTrackingHandler.

ChannelServices.RegisterChannel( new TcpChannel( 4000 ) );
 // this will handle converting the returned CAO uri to the correct server IP 
TrackingServices.RegisterTrackingHandler(new ExampleTrackingHandler());
 Type thisType = Type.GetType("Server.SAOCAOClassFactory,Server");
 RemotingConfiguration.RegisterWellKnownServiceType(thisType, 
      "SAOCAOClassFactoryURI", WellKnownObjectMode.SingleCall ); 

Thats all you need!? At this point you can instantiate your CAO from the client with your SAO factory.?If you have any comments, recommendations, questions, feel free to contact me. I try to answer? all of my email.

I've tested all the code several times to make sure I didn't include any errors, however if you do find any mistakes or have any questions, feel free to email me allen@glacialcomponents.com.?