转自:http://www.eb163.com/club/thread-6471-1-1.html
不论是低于还是高于1024端口,基于文件系统时都不会请求策略文件,基于网络时才会请求.
1.首先发出以null结尾的<policy-file-request/>的消息,检查服务器843端口是否有安全策略文件,策略文件格式为:
<allow-access-from domain="*" to-ports="80-9000" />
</cross-domain-policy>
发回策略文件的时候必要以0结尾,如果843端口在3秒内没有请求到策略文件或者to-ports配置的端口不允许链接,则断掉链接抛securityError,这个是flash主动发起的.
2. 如果您的客户端socket或xmlsocket连接中设置了Security.loadPolicyFile("xmlsocket://服务地址:应用端口"),则连接您的应用目标端口请求安全策略文件,请求和响应的方式如上,不设置是不会请求的.发请求是在调用connect之前.
3. 如果您是http请求方式要设置Security.loadPolicyFile("http://服务地址/crossdomain.xml"),crossdomain.xml文件内容如上,放在网站根目录就行了.例如mop的http://www.mop.com/crossdomain.xml
解决方案1:使用adobe官方提供的文件直接在服务器的843端口上建立服务,这样响应速度最快,但对于应用的部署就麻烦了http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html
解决方案2:客户端必须加Security.loadPolicyFile("xmlsocket://服务地址:应用端口"),在服务端的应用端口上的私有协议上处理,一般的协议是长度+类型+数据,这样判断长度是0x3C70类型0x6C69,单独处理这个消息,但对自己的私有协议处理还是有影响。
为什么是这样的长度和类型看图:
解决方案3:单独在服务应用上处理843端口,和其他应用的服务剥离出来:

public void startPolicyServer() throws IOException{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.setHandler(new PolicyServerHandler());
acceptor.bind( new InetSocketAddress(843));
System.out.println("安全策略服务侦听端口:843");
}
//其他应用服务
..................
..................
//单独的安全策略处理器
public class PolicyServerHandler extends IoHandlerAdapter {
// 22字节+0占1个字节
String security_quest = "<POLICY-FILE-REQUEST />";
// 最后以0结尾
String policyStr = "<CROSS-DOMAIN-POLICY>\r\n<ALLOW-ACCESS-FROM to-ports='\"80-9000\"' domain='\"*\"' />\r\n </CROSS-DOMAIN-POLICY>\r\n\0";
private
final Logger log = Logger.getLogger(PolicyServerHandler.class.getName());
public
void messageReceived(IoSession session, Object message)
throws Exception {
IoBuffer processBuf = (IoBuffer) session.getAttribute("processBuf");
processBuf.put((IoBuffer)message);
processBuf.flip();
if(getRequest(processBuf)){
byte[] reps = policyStr.getBytes("UTF-8");
IoBuffer rb = IoBuffer.allocate(reps.length);
rb.put(reps);//也有putString方法
rb.flip();
session.write(rb);//发回
log.info("send Policy");
}
}
//获得安全请求的字符串
private
Boolean getRequest(IoBuffer buf){
String req = new
String(buf.array());
if (req.indexOf(security_quest) != -1){
return
true;
}
return
false;
}
@Override
public
void messageSent(IoSession session, Object message) throws Exception {
session.close(true);
}
@Override
public
void sessionClosed(IoSession session) throws Exception {
super.sessionClosed(session);
session.removeAttribute("processBuf");
}
@Override
public
void sessionCreated(IoSession session) throws Exception {
super.sessionCreated(session);
IoBuffer processBuf = IoBuffer.allocate(64);
session.setAttribute("processBuf", processBuf);
}
}
}
c#:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; using System.Xml; namespace Server { class Program { static void Main( string [] args) { try { int port = 60002; string host = "192.168.1.103" ; IPAddress ip = IPAddress.Parse(host); IPEndPoint ipe = new IPEndPoint(ip, port); Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建一个Socket类 s.Bind(ipe); s.Listen(0); Console.WriteLine( "Wait for connect 60002" ); while ( true ) { try { Socket temp = s.Accept(); //为新建连接创建新的Socket。 Console.WriteLine( "Get a new connect " + DateTime.Now.ToString()); string recvStr = "" ; byte [] recvBytes = new byte [1024]; int bytes; bytes = temp.Receive(recvBytes, recvBytes.Length, 0); //从客户端接受信息 recvStr += Encoding.GetEncoding( "UTF-8" ).GetString(recvBytes, 0, bytes); Console.WriteLine( "Server Get Message: {0}" , recvStr); //把客户端传来的信息显示出来 if (recvStr == "<policy-file-request/>\0" ) { String sendStr = "<cross-domain-policy><allow-access-from domain=\"192.168.1.102\" to-ports=\"60000-60010\"/></cross-domain-policy>\0" ; byte [] bs = Encoding.GetEncoding( "UTF-8" ).GetBytes(sendStr); temp.Send(bs, bs.Length, 0); //返回客户端成功信息 Console.WriteLine( "Send: " + sendStr); //temp.Close(); //s.Close(); } else { string sendStr = "Ok!Client Send Message Sucessful!" ; byte [] bs = Encoding.GetEncoding( "UTF-8" ).GetBytes(sendStr); temp.Send(bs, bs.Length, 0); //返回客户端成功信息 //temp.Close(); //s.Close(); } } catch (Exception ex) { Console.WriteLine( "SocketException: {0}" , ex); } } } catch (Exception ex2) { Console.Write(ex2.Message.ToString()); } } } } |
备注:
1 mina2.x对比1.x效率更高,抛弃了原有的btyeBuffer,新写了Iobuffer,原因如下:
It doesn't provide useful getters and putters such as fill, get/putString, and get/putAsciiInt() enough.
It is difficult to write variable-length data due to its fixed capacity
2 demux下DemuxingProtocolCodecFactory和MessageDecoder等功能更完善了,decodable判断是否能解析数据,decode解析实际的数据,在处理私有协议上更简单了
3 Flash10 socket类新增加timeout属性指示建立连接时需等待的毫秒数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述