转贴一个简单的web服务器:
httpd.erl
%% httpd.erl - microhttpd
-module(httpd).
-author("ninhenry@gmail.com").
-export([start/0,start/1,start/2,process/2]).
-import(regexp,[split/2]).
-define(defport,8888).
-define(docroot,"public").
start() -> start(?defport,?docroot).
start(port) -> start(port,?docroot).
start(port,docroot) ->
case gen_tcp:listen(port, [binary,{packet, 0},{active, false}]) of
{ok, lsock} -> server_loop(lsock,docroot);
{error, reason} -> exit({port,reason})
end.
%% main server loop - wait for next connection, spawn child to process it
server_loop(lsock,docroot) ->
case gen_tcp:accept(lsock) of
{ok, sock} ->
spawn(?module,process,[sock,docroot]),
server_loop(lsock,docroot);
{error, reason} ->
exit({accept,reason})
end.
%% process current connection
process(sock,docroot) ->
req = do_recv(sock),
{ok,[cmd|[name|[vers|_]]]} = split(req,"[ \r\n]"),
filename = docroot ++ name,
logreq = cmd ++ " " ++ name ++ " " ++ vers,
resp = case file:read_file(filename) of
{ok, data} ->
io:format("~p ~p ok~n",[logreq,filename]),
data;
{error, reason} ->
io:format("~p ~p failed ~p~n",[logreq,filename,reason]),
error_response(logreq,file:format_error(reason))
end,
do_send(sock,resp),
gen_tcp:close(sock).
%% construct html for failure message
error_response(logreq,reason) ->
"<html><head><title>request failed</title></head><body>\n" ++
"<h1>request failed</h1>\n" ++ "your request to " ++ logreq ++
" failed due to: " ++ reason ++ "\n</body></html>\n".
%% send a line of text to the socket
do_send(sock,msg) ->
case gen_tcp:send(sock, msg) of
ok -> ok;
{error, reason} -> exit(reason)
end.
%% receive data from the socket
do_recv(sock) ->
case gen_tcp:recv(sock, 0) of
{ok, bin} -> binary_to_list(bin);
{error, closed} -> exit(closed);
{error, reason} -> exit(reason)
end
运行时在httpd.erl本地建一个public目录,public目录里放一个index.html文件
然后httpd:start()启动服务器,就可以访问http://localhost:8888/index.html了
发表评论