- 浏览: 242518 次
- 性别:
- 来自: 沈阳
文章分类
最新评论
-
Araxis:
也遇到了楼主的问题,我用的sockjs.0.3.4,升级版本到 ...
Websocket出现的错误 -
love_jun1314:
怎么进行转换成功并没有看到a.flv文件呢? 你把commen ...
java调用ffmpeg执行视频转换 -
枫林top:
不错,挺好的
看老外程序员如何向妻子解释设计模式 -
likj_sh:
太感谢了 ,困惑了好久
Struts2 + Spring + Hibernate + DWR 项目布署笔记 -
dhl004:
...
web.xml 通过contextConfigLocation配置spring 的方式
简介
policy-file是flash socket安全机制的重要部分,而本文详细介绍提供policy-file的policyserver的实现过程。事实上,policyserver本身也是一个socket服务器端的简单原型。了解本文也将为教程中后续的sessionserver的讨论有所铺垫。
什么是policy-file
policy-file是一个flash的安全控制机制,它的设置决定了是否允许flash程序进行跨域通讯。这是对ajax,dom无法跨域的一个拓展。
一个典型的policy-file可能是这样的:
<?xml version="1.0" encoding="UTF-8"?> <cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd"> <allow-access-from domain="*" to-ports="*" secure="false" /> <site-control permitted-cross-domain-policies="master-only" /> </cross-domain-policy>
其中你可以在policy-file指定允许开放的域名/ip,或者是端口。
policy-file的请求过程
1 flash socket在真正执行socket.connect,以连接到指定的ip和端口前,会先尝试连接该ip的843端口
2如果843端口被监听,并且在连接上后接收到一个policy-file.xml的话,才会断开与843端口的连接
3 flash会分析policy-file的内容,并确认是否访问指定的ip和端口是否是被允许的
4 如果指定的ip和端口是否是被允许的,flash才会真正的连接到指定的ip和端口
policy-file的请求过程的异常情况
1 如果843端口连接失败或者超时,flash依然会连接指定端口,并尝试从指定端口获取policy-file
2如果policy-file获取失败,或者指定的ip和端口不在policy-file允许范围内,flash socket将抛出flash.events.SecurityErrorEvent.SECURITY_ERROR这个异常
policyserver的实现
监听端口
IPAddress ipAddress = IPAddress.Parse(ip); IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 843); Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { listener.Bind(localEndPoint); listener.Listen(100); while (true) { allDone.Reset(); listener.BeginAccept( new AsyncCallback(AcceptCallback), listener); allDone.WaitOne(); } } catch (Exception e) { Console.WriteLine(e.ToString()); }
其中allDone是一个信号控制变量。在接收到一个新的连接请求前,policyserver会阻塞在allDone.WaitOne()这一句。
处理接入请求
public static void AcceptCallback(IAsyncResult ar) { allDone.Set(); Socket listener = (Socket) ar.AsyncState; Socket handler = listener.EndAccept(ar); Console.WriteLine("conneceted : " + handler.RemoteEndPoint.ToString()); StateObject state = new StateObject(); state.workSocket = handler; handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); }
在上面的代码里,我还把客户端的ip写入控制台,并将异步接受flash的第一个请求。
读入请求,写回policy-file
当接入一个连接请求以后,allDone.Set()释放信号量,在等待接入的循环体里,将完成一次过程,进入下一次循环。
public static void ReadCallback(IAsyncResult ar) { String content = String.Empty; StateObject state = (StateObject) ar.AsyncState; Socket handler = state.workSocket; int bytesRead = handler.EndReceive(ar); if (bytesRead > 0) { state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead)); content = state.sb.ToString(); if ("<policy-file-request/>/0" == content) { Send(handler, @" <?xml version=""1.0"" encoding=""UTF-8""?> <cross-domain-policy xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd""> <allow-access-from domain=""*"" to-ports=""*"" secure=""false"" /> <site-control permitted-cross-domain-policies=""master-only"" /> </cross-domain-policy> "); } else { handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } }
写完策略文件后,在控制台写入作为提示信息。并关闭socket。
配置
考虑到这个policyserver可能部署在不同的环境,为了方便部署,我从文件名中读取配置。
Match m = Regex.Match(Environment.CommandLine, @"/d+/./d+/./d+/./d+"); string ip = string.IsNullOrEmpty(m.Value) ? "127.0.0.1" : m.Value; Console.WriteLine("binding to " + ip);
比如编译结果文件为SimplePolicyServer.exe,我把它文件名修改为SimplePolicyServer.192.168.1.10.exe ,那么它在执行的时候,便会监听192.168.1.10这个ip的端口。如果没有指定正确的ip的话,默认绑定到本机,即127.0.0.1。
完整代码
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Net.NetworkInformation; using System.Text.RegularExpressions; public class StateObject { public Socket workSocket = null; public const int BufferSize = 1024; public byte[] buffer = new byte[BufferSize]; public StringBuilder sb = new StringBuilder(); } namespace SimplePolicyServer { class Program { // Thread signal. public static ManualResetEvent allDone = new ManualResetEvent(false); public static void StartListening() { byte[] bytes = new Byte[1024]; Match m = Regex.Match(Environment.CommandLine, @"/d+/./d+/./d+/./d+"); string ip = string.IsNullOrEmpty(m.Value) ? "127.0.0.1" : m.Value; Console.WriteLine("binding to " + ip); IPAddress ipAddress = IPAddress.Parse(ip); IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 843); Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { listener.Bind(localEndPoint); listener.Listen(100); while (true) { allDone.Reset(); listener.BeginAccept( new AsyncCallback(AcceptCallback), listener); allDone.WaitOne(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.Read(); } public static void AcceptCallback(IAsyncResult ar) { allDone.Set(); Socket listener = (Socket) ar.AsyncState; Socket handler = listener.EndAccept(ar); Console.WriteLine("conneceted : " + handler.RemoteEndPoint.ToString()); StateObject state = new StateObject(); state.workSocket = handler; handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } public static void ReadCallback(IAsyncResult ar) { String content = String.Empty; StateObject state = (StateObject) ar.AsyncState; Socket handler = state.workSocket; int bytesRead = handler.EndReceive(ar); if (bytesRead > 0) { state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead)); content = state.sb.ToString(); if ("<policy-file-request/>/0" == content) { Send(handler, @" <?xml version=""1.0"" encoding=""UTF-8""?> <cross-domain-policy xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd""> <allow-access-from domain=""*"" to-ports=""*"" secure=""false"" /> <site-control permitted-cross-domain-policies=""master-only"" /> </cross-domain-policy> "); } else { handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } } private static void Send(Socket handler, String data) { byte[] byteData = Encoding.ASCII.GetBytes(data); handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); } private static void SendCallback(IAsyncResult ar) { try { Socket handler = (Socket) ar.AsyncState; int bytesSent = handler.EndSend(ar); Console.WriteLine("policy file sent"); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } public static int Main(String[] args) { StartListening(); return 0; } } }
发表评论
-
用JavaScript玩转游戏物理(一)运动学模拟与粒子系统
2017-09-16 22:28 657系列简介 也许,三百 ... -
30分钟掌握ES6/ES2015核心内容
2017-01-09 11:21 410ECMAScript 6(以下简称ES6)是JavaSc ... -
requirejs、require方法冲突
2016-12-21 18:10 1547如果加载了多个requirejs脚本,每个requirejs ... -
谈谈使用 promise 时候的一些反模式
2016-11-25 15:20 404本文翻译自 We have a problem with ... -
HTML5 Canvas实现平移/放缩/旋转deom示例(附截图)
2016-11-23 12:11 647HTML5 Canvas中提供了 ... -
移动端H5页面高清多屏适配方案
2016-11-17 08:35 831背景 开发移动端H5页面 面对不同分辨率的 ... -
使用Flexible实现手淘H5页面的终端适配rem自适应布局-移动端自适应必备
2016-11-03 23:52 721曾几何时为了兼容IE低版本浏览器而头痛,以为到Mobile时 ... -
CSS3的calc()使用
2016-11-03 21:51 661calc()对大家来说,或许很陌生,不太会相信calc()是 ... -
CSS3的REM设置字体大小
2016-11-03 21:50 672在Web中使用什么单位来定义页面的字体大小,至今天为止都还在 ... -
JavaScript Promises 相当酷
2016-09-02 18:53 516And when I promise some ... -
gulp使用小结
2016-05-22 19:02 649这篇文章不会介绍 gulp 的起源、发展;不会去一个个讲解 ... -
用gulp做一个略完整的前端打包工作
2016-05-22 18:59 2428我们的官网要改版,会从以前的单一产品变成 ... -
前端神器avalonJS入门
2016-05-19 19:32 591本章将介绍如何使用avalon来实现前端路由功能。 我们需 ... -
给Webstorm的HTML自动压缩插件
2016-05-07 14:20 1254前端代码的压缩 前端的js、css、html的压缩不仅会让 ... -
gulp教程之gulp中文API
2016-05-07 13:44 564http://www.ydcss.com/ ... -
gulp详细入门教程
2016-05-07 13:00 549简介: gulp是前端开发过程中对代码进行构建的工具, ... -
HTML5 Boilerplate - 让页面有个好的开始
2016-04-20 19:08 667一:HTML5 Boilerplate是什 ... -
来,让我们谈一谈 Normalize.css
2016-04-20 19:07 450本文译自Normalize.css官网: http:// ... -
Websocket出现的错误
2016-04-06 10:49 7000前端使用sockjs,后台使用spring的websocke ... -
移动平台的meta标签-----神奇的功效
2016-02-18 10:51 461对于桌面平台web布局中大家对meta标签再熟悉不过了,它永 ...
相关推荐
仅使用Python基础从头开始构建大型语言模型;从零开始逐步构建GLM4-Lama3-RWKV6,深入了解大型模型的原理.zip仅使用Python基础从头开始构建大型语言模型;从零开始逐步构建GLM4-Lama3-RWKV6,深入了解大型模型的原理...
### 从头开始构建一个嵌入式Linux发行版 #### 目标与概述 本教程旨在展示如何在目标系统上自行构建并安装Linux系统。这一过程并非简单的预装发行版安装,而是通过从零开始的方式,使用户能够在目标设备上运行...
《Python-引导自己从头开始编写一个操作系统》是一本面向自学者的书籍,旨在帮助读者深入理解操作系统的原理,并通过Python语言实现一个简单的操作系统。在学习过程中,你可以掌握计算机系统的基础知识,了解操作...
DIY-Deep-Learning-Workstation, 从头开始构建一个深入学习工作站 DIY-Deep-Learning-Workstation从头构建一个深度学习工作站。 本文档是为 14.04编写的,但大多数步骤也应适用于其他Ubuntu版本和leanring框架。具有...
"Open-IM-Server"是一个开源即时通讯(IM)服务器,专为构建高效、安全的实时通信系统设计。本文将深入探讨Open-IM-Server的关键技术、架构、功能以及如何利用它来搭建自己的IM服务。 1. **Open-IM-Server概述** ...
mini-arm-os, 从头开始构建 ARM Cortex M 系列的最小多任务操作系统内核 构建最小的多任务操作系统内核先决条件带有STM32微控制器实现的 QEMU 。生成说明./configure --disable-werror --enable-debug --target-list...
角滚动间谍从头开始构建的简单,轻量级的scroll-spy伪指令。 它在元素滚动到视图或视图之外时广播事件。用法在要为其接收滚动事件的元素上添加scroll-spy属性和id 。 当元素首次滚动到视图中时,会触发一次'...
app-datepicker, 使用聚合物从头开始构建的元件 应用程序 datepicker ( 以前为 jv-datepicker ) 有关详细信息...一个自定义的聚合物元素,从头开始提供一个基于谷歌设计的更具吸引力和丰富性的。实时更新( )高兴宣布 ap
描述中的“系列”可能意味着这是一个多部分的教程或者项目,逐步引导开发者了解如何从零开始构建一个完整的后台管理系统。企业级后台管理系统通常包括用户管理、权限控制、数据展示、业务流程处理等功能。使用 Vue ...
用于构建Linux从头开始系统的Docker配置
此应用程序将执行一个设计,通过集成从多个服务器端 API 请求接收的数据来解决实际问题。项目团队作者项目资源: :backhand_index_pointing_right: :backhand_index_pointing_right: :backhand_index_pointing_...
从头开始构建前端Web应用程序是一个Codecademy Pro Intensive程序,涵盖了专业人员使用React开发Web应用程序所使用的技能。 目录 扫雷车 一个基于控制台的扫雷游戏。 要添加的功能 添加验证以确保电路板尺寸合理。 ...
在本教程中,我们将深入探讨如何使用AngularJS框架从零开始构建一个Web应用程序。AngularJS是Google维护的一个开源JavaScript框架,它主要用于构建单页应用程序(SPA)。这个框架以其数据绑定和依赖注入特性而闻名,...
教程:如何从头开始构建Spring Boot Web应用程序 本教程使用Oracle JDK 8,Spring Boot,Spring Data,Thymeleaf构建。 如何使用它 ? 安装JDK 8: : 安装Maven: : 克隆存储库 mvn包 java -jar target / first...
从零开始React从头开始构建React Progressive Web App 该项目是在现代Web应用程序开发中尝试多种技术的游乐场。 但是,有意地,应用程序本身根本没有任何作用。 特别感谢Udacity / Google Web专家奖学金及其始终支持...
Java SDK是许多软件开发中的重要组成部分,特别是在与服务器端交互时...通过学习和使用这个SDK,开发者可以迅速在自己的应用中实现稳定、可靠的即时通信功能,而无需从头构建整个通讯系统,大大节省了开发时间和资源。
我们将从头开始,一步步地搭建整个系统,以便读者能够轻松地搭建自己的 RustDesk 远控软件。 搭建节点服务器 要搭建 RustDesk 远控软件的节点服务器,我们需要满足以下条件: 1. 自有一台服务器 2. 会搭建基本的...
JavaScript Shadow是一个创新的Web引擎项目,它展示了JavaScript语言在构建高性能网络应用方面的潜力。这个引擎几乎完全使用JavaScript从头开始编写,打破了传统上由C++或Rust等系统级语言主导的浏览器内核构建模式...
《Java Web 服务:构建与运行(影印版)》提供了对Java的API的一个全面介绍,包括针对XML Web服务的JAX-WS和针对RESTful Web服务的JAX-RS。《Java Web服务:构建与运行》通过提供混合架构概述、完整的工作代码示例...
[tutsplus] 使用 AngularJS 从头开始构建 Web 应用程序