2008年9月15日 星期一

封存網誌

這個網誌將不再更新,僅用於封存以前的文章,也不再提供留言功能。之前的文章我僅挑了些可能有用的出來,其他的都刪掉了。

以Erlang實作Port Mapping

最近又開始在閒暇時看Erlang的東西....
練習寫了一些簡單的東西,如這個映射TCP Port的程式 (將本地port映設到其他host的port)
例如 tcp_bridge:start("ptt.cc", 23, 1000) 後, telnet localhost:1000就會連到ptt bbs

-module(tcp_bridge).
-export([start/3]).
start(IP, Port, LocalPort) ->
{ok, ListenSocket} = gen_tcp:listen( LocalPort, [list, inet, {packet, raw}] ),
spawn( fun() -> listen_loop(ListenSocket, IP, Port) end ).
listen_loop(ListenSocket, IP, Port) ->
{ok, LocalSocket} = gen_tcp:accept(ListenSocket),
{ok, RemoteSocket} = gen_tcp:connect(IP, Port, [list, inet, {packet, raw}], 3000),
bridge(LocalSocket, RemoteSocket),
bridge(RemoteSocket, LocalSocket),
listen_loop(ListenSocket, IP, Port).
bridge(RecvSocket, SendSocket) ->
Receiver = spawn(fun() -> reciever(RecvSocket, SendSocket) end),
gen_tcp:controlling_process(RecvSocket, Receiver),
Receiver.
reciever(RecvSocket, SendSocket) ->
receive
{tcp, _Socket, Data} ->
gen_tcp:send(SendSocket, Data),
reciever(RecvSocket, SendSocket);
{tcp_closed, _Socket} ->
gen_tcp:close(SendSocket);
die ->
gen_tcp:close(SendSocket);
_ ->
void
end.
view raw gistfile1.erl hosted with ❤ by GitHub


其實上面的實作碼潛藏著一些問題,但是當作一個telnet的跳版已經夠用了。
這個邏輯以Erlang實作算是相當精簡的。