Erlang实现简单Web服务器

转贴一个简单的Web服务器: 
httpd.erl 
Java代码 
  1. %% httpd.erl - MicroHttpd  
  2. -module(httpd).  
  3. -author("ninhenry@gmail.com").  
  4.   
  5. -export([start/0,start/1,start/2,process/2]).  
  6. -import(regexp,[split/2]).  
  7.   
  8. -define(defPort,8888).  
  9. -define(docRoot,"public").  
  10.   
  11. start() -> start(?defPort,?docRoot).  
  12. start(Port) -> start(Port,?docRoot).    
  13. start(Port,DocRoot) ->  
  14.   case gen_tcp:listen(Port, [binary,{packet, 0},{active, false}]) of  
  15.     {ok, LSock} -> server_loop(LSock,DocRoot);  
  16.       {error, Reason}   -> exit({Port,Reason})  
  17.   end.  
  18.   
  19. %% main server loop - wait for next connection, spawn child to process it  
  20. server_loop(LSock,DocRoot) ->  
  21.   case gen_tcp:accept(LSock) of  
  22.     {ok, Sock} ->  
  23.       spawn(?MODULE,process,[Sock,DocRoot]),  
  24.       server_loop(LSock,DocRoot);  
  25.     {error, Reason} ->  
  26.       exit({accept,Reason})  
  27.   end.  
  28.   
  29. %% process current connection  
  30. process(Sock,DocRoot) ->  
  31.   Req = do_recv(Sock),  
  32.   {ok,[Cmd|[Name|[Vers|_]]]} = split(Req,"[ \r\n]"),  
  33.   FileName = DocRoot ++ Name,  
  34.   LogReq = Cmd ++ " " ++ Name ++ " " ++ Vers,  
  35.   Resp = case file:read_file(FileName) of  
  36.     {ok, Data} ->  
  37.       io:format("~p ~p ok~n",[LogReq,FileName]),  
  38.       Data;  
  39.     {error, Reason} ->  
  40.       io:format("~p ~p failed ~p~n",[LogReq,FileName,Reason]),  
  41.       error_response(LogReq,file:format_error(Reason))  
  42.     end,   
  43.   do_send(Sock,Resp),  
  44.   gen_tcp:close(Sock).  
  45.   
  46. %% construct HTML for failure message  
  47. error_response(LogReq,Reason) ->  
  48.   "<html><head><title>Request Failed</title></head><body>\n" ++  
  49.   "<h1>Request Failed</h1>\n" ++ "Your request to " ++ LogReq ++  
  50.   " failed due to: " ++ Reason ++ "\n</body></html>\n".  
  51.   
  52. %% send a line of text to the socket  
  53. do_send(Sock,Msg) ->  
  54.   case gen_tcp:send(Sock, Msg) of  
  55.     ok -> ok;  
  56.       {error, Reason} -> exit(Reason)  
  57.   end.  
  58.   
  59. %% receive data from the socket  
  60. do_recv(Sock) ->  
  61.   case gen_tcp:recv(Sock, 0) of  
  62.     {ok, Bin} -> binary_to_list(Bin);  
  63.       {error, closed} -> exit(closed);  
  64.       {error, Reason} -> exit(Reason)  
  65.   end.  

运行时在httpd.erl本地建一个public目录,public目录里放一个index.html文件 
然后httpd:start()启动服务器,就可以访问http://localhost:8888/index.html了
posted @ 2010-08-06 17:32  麦飞  阅读(4098)  评论(1编辑  收藏  举报