学习ERLANG 2周,用它写了一个假WEB服务器

写这个程序主要是为了熟悉它的语法。

功能:一个假WEB服务器,很多缺陷,还要完善。
使用:

1.编译web.erl。然后在ERLANG环境中用命令web:start().启动。

2.文件请求,你把文件放在当前目录下,如hello.html,输入http://localhost:8800/hello.html.

3.数据请求(相当于JAVA中的servlet),当你输入http://localhost:8800/erlang/mode/func的时候,它回去请求一个叫mode:func(Param)的函数,其中Param是GET和POST传递过来的参数,函数返回值会被传送到页面,当然你必须先编译了这个模块。

4.如果请求失败,也许会导致程序崩溃,哈哈,比如文件不存在。

 

下面是源代码:

 

-module(web).
-export([start/0]).

%%启动服务
start() ->
    {ok, LSock} = gen_tcp:listen(8800, [binary, {packet, 0},{active, false}]),
    seq_loop(LSock).
                      
%%请求队列循环 
seq_loop(LSock) ->
   {ok, Sock} = gen_tcp:accept(LSock),
   req_loop(Sock),
   seq_loop(LSock).
  
%%请求处理循环
req_loop(Sock) ->
    case gen_tcp:recv(Sock, 0) of
        {ok, Req} ->
          ok = analyse(Req),
          respones(Sock),
            req_loop(Sock);
        {error, closed} ->
            ok
    end.
%%回应   
respones(Sock)->
  S = case get(mode) of
   erlang ->
     apply(get(module),get(func),[lists:append(get(get),get(post))]);
   _ ->
     io:format("~p~n",[get(file)]),
     {ok,DATA} = file:read_file(get(file)),
     DATA
     end,
    ok = gen_tcp:send(Sock, S),
    ok = gen_tcp:close(Sock).
   

%% 请求分析
analyse(Req) ->
  [H|T]= string:tokens(binary_to_list(Req),"/r/n"),
  %获得请求路径和请求GET参数
  [M,P,V] = string:tokens(H," "),
  put(method,M),
  put(ver,V),
  %%分析GET参数
  PP = string:tokens(P,"?"),
  case length(PP) of
    2 ->
     [H1|[T1]]=PP,
     server(H1),
     put(get,param(T1));
    _ ->
     [PP1]=PP,
     server(PP1)
  end,
  put(server,P),
  ok = analyse1(T),
  ok.
analyse1([H|T]) ->
  M = string:tokens(H,":"),
  case length(M) of
   1 -> %post参数
    [M1]=M,
    put(post,param(M1)),
    analyse1(T);
   2 ->
    [K,V]=M,
    case K of
     "Accept-Language" ->
      put(language,V),
      analyse1(T);
     "Accept-Encoding" ->
      put(encoding,V),
      analyse1(T);
     _ ->
      analyse1(T)
    end;
   3 ->
    [_,IP,PORT] = M,
    put(host,IP),
    put(port,PORT),
    analyse1(T);
   _ ->
    analyse1(T)
  end;
analyse1([]) ->
  ok.

%分析请求服务类型,如果get为/erlang/[Mod]/[Fun]则为请求数据服务,否则为文件请求
server(P) ->
  [H|T]=string:tokens(P,"/"),
  case H of
   "erlang" ->
     [Mod|[Fun]]=T,
     put(mode,erlang),
     put(module,list_to_atom(Mod)),
     put(func,list_to_atom(Fun));
   _ ->
     [_H1|T1]=P,
     put(mode,file),
     put(file,T1)
   end.  
%格式化参数
param(Pas) ->
  Pa= string:tokens(Pas,"&"),
  param(Pa,[]).
param([H|T],P) -> 
  M = string:tokens(H,"="),
  case length(M) of
   1 ->
     param(T,[{M,nil}|P]);
   2 ->
     [H1|[T1]]= M,
     param(T,[{H1,T1}|P]);
   _ ->
     param(T,P)
  end;
param([],P) ->
  P.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值