zoukankan      html  css  js  c++  java
  • flash游戏服务器安全策略

       在网页游戏开发中,绝大多数即时通信游戏采用flash+socket 模式来作为消息数据传递。在开发过程中大多数开发者在开发过程中本地没有问题,但是一旦部署到了网络,就存在连接上socket服务器。究其原因主要是没有部署安全策略文件。在这里我主要说说flash策略文件部署。

    1.flash安全策略文件格式 

    <?xml version="1.0"?>
    <!DOCTYPE cross-domain-policy SYSTEM  "/xml/dtds/cross-domain-policy.dtd">
    <cross-domain-policy>
        <allow-access-from domain="*" to-ports="*" />
    </cross-domain-policy>

       1.1 domain 请求服务来源地 可以是ip,也可以是域名 也可以是域名通配  eg: 192.168.1.110, www.***.com, *.foo.com

       1.2 to_ports 容许程序访问的端口 “*”代表可以访问的端口。当然为了安全起见个人建议填写能访问的端口。

    2.策略文件的主要作用 

       2.1 让跨域机器能访问当前服务器的资源。

       2.2 保护本机网络资源不被其余flash调用。

    3.策略文件的部署方式

      3.1 部署一个http服务器在当前的服务器并在网站的根目录下放crossdomain.xml文件

      3.2 开一个843端口的socket服务器,专门处理用于发送crossdomian.xml 内容,发送完毕立即关闭socket 断开tcp

    4. 游戏开发中处理

      4.1 一般在静态资源处理控制授权的时候,部署得有http服务器 这个时候一般采用在可访问的资源目录下存放crossdomain.xml

      4.2 在仅仅只有部署socket服务的时候一般采用843 端口处理策略文件。

      4.3 当游戏服务器中既有http服务 也有socket 服务的时候 也可以直接部署http 放crossdomain.xml。个人建议还是采用开843端口socket处理。flash启动的时候时候会默认先尝试连接843端口接收数据,然后在访问http根目录数据。导致socket连接缓慢给用户体验不是很好。

    5.用erlang实现一个切实可用的socket 843服务器,整个实现过程我在 ranch实现游戏服务器 的基础上稍加改动即实现了。

      5.1 去掉 game_socket_app.erl 中     ok = game_socket_store:init(), 即可。

       
    -module(game_socket_app).
    
    -behaviour(application).
    
    %% Application callbacks
    -export([start/2, stop/1]).
    
    -define(PORT,9933).
    -define(LISTEMNUM,5).
    
    %% ===================================================================
    %% Application callbacks
    %% ===================================================================
    
    start(_StartType, _StartArgs) ->
        Port = case application:get_env(game_socket, port) of
                   {ok, P} -> P;
                   undefined -> ?PORT
               end,
        ListenNum = case application:get_env(game_socket,listemnum) of
            {ok,L}->L;
             undefined->?LISTEMNUM
            end, 
        case game_socket_sup:start_link([Port,ListenNum]) of
            {ok, Pid} ->
                {ok, Pid};
            Other ->
                {error, Other}
        end.
    
    stop(_State) ->
        ok.
    View Code

      5.2 在 game_socket_server.erl 接收到客户端发送数据后发送策略文件,本文没有对客户端发送的数据做匹配。如果需要请自行处理。

      
    -module(game_socket_server).
    -behaviour(gen_server).
    -behaviour(ranch_protocol).
    
    %% API.
    -export([start_link/4]).
    
    %% gen_server.
    -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
             terminate/2, code_change/3]).
    
    -define(TIMEOUT, 3000).
    
    -define(SERVER, ?MODULE).
    
    -define(GENERIC_POLICY_FILE,
            <<"<?xml version=\"1.0\"?>"
             "<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">"
             "<cross-domain-policy>"
             "    <allow-access-from domain=\"*\" to-ports=\"*\" />"
             "</cross-domain-policy>">>).
    
    -record(state, {ref,socket, transport,otp,ip,port,timeref}).
    %% API.
    
    start_link(Ref, Socket, Transport, Opts) ->
        gen_server:start_link(?MODULE, [Ref, Socket, Transport, Opts], []).
    
    %% gen_server.
    
    %% This function is never called. We only define it so that
    %% we can use the -behaviour(gen_server) attribute.
    
    init([Ref, Socket, Transport,Opts]) ->
        %%防攻击使用 多个连接建立后不给消息 造成端口占用
        {ok,TimeRef} = timer:send_after(?TIMEOUT,self(),disconnect),    
        {ok,{Address,Port}} = inet:peername(Socket),
        {ok, {state, Ref, Socket, Transport,Opts,Address,Port,TimeRef}, 0}.
    %% timout function set opt parms
    handle_info(timeout, State=#state{ref=Ref, socket=Socket, transport=Transport}) ->
        ok = ranch:accept_ack(Ref),
        ok = Transport:setopts(Socket, [{active, once}]),
        {noreply, State};
    %% 主动断开连接
    handle_info(disconnect,State=#state{timeref = TimeRef})->
        timer:cancel(TimeRef),
        {stop,normal,State};
    %% handle socket data 
    handle_info({tcp, Socket, _Data}, State=#state{socket=Socket, transport=Transport}) ->
             Transport:send(Socket,?GENERIC_POLICY_FILE),
        {stop, normal, State};
    handle_info(_Info, State) ->
        {stop, normal, State}.
    
    handle_call(_Request, _From, State) ->
        {reply, ok, State}.
    
    handle_cast(_Request, State) ->
        {noreply, State}.
    
    terminate(_Reason, _State) ->
        ok.
    
    code_change(_OldVsn, State, _Extra) ->
        {ok, State}.
    View Code

          到这里一个可以用于实际生产环境的socket 843服务器就完成了。怎么样?简单吧! 

      

  • 相关阅读:
    VS2012写的程序在VS2010打开时显示当前版本不兼容
    (转载)Sumblime Text 2 常用插件以及安装方法
    (转载)Nginx防盗链的几种方法
    C#对字符串执行字节操作
    转载:自动生成数据库文档
    SQL SERVER “扩展属性"的应用
    使用EventLog实现事件日志操作
    SQL SERVER2005无日志文件附加数据库最简单的方法(转载)
    网站分析工具Google Analytics
    学习使用master.dbo.spt_values表
  • 原文地址:https://www.cnblogs.com/codew/p/3829850.html
Copyright © 2011-2022 走看看