ARTICLES
Written by Raimo, 26 Apr 2010
A simple telnet client
%%
%% getty.erl
%%
%% Author: Sebastian Strollo [seb@erix.ericsson.se]
%%
-module(getty).
-export([start/0, start/1, start/2]).
-export([init/2, l/2]).
%%
%% Interface: start( Port , {Mod, Fun} )
%%
%% Starts a "getty" process that listens on TCP port Port, and spawns
%% {Mod, Fun, [self()]} after accepting a connection on that port.
%%
start(PortNo, MF) ->
spawn(?MODULE, init, [PortNo, MF]).
%%
%% Defaults - start {user, server} on port 7788
%%
start() ->
start(7788).
start(PortNo) when integer(PortNo) ->
start(PortNo, {user, server}).
%% ----------------------------------------------------------------------
init(PortNo, MF) ->
process_flag(trap_exit, true),
{ok, LS} = gen_tcp:listen(PortNo, [{reuseaddr, true}, {packet, 0},
{active, false}]),
g_loop(LS, MF).
%%
%% Main loop
%%
g_loop(S, MF) ->
{ok, NS} = gen_tcp:accept(S), % accept new connection
Pid = spawn(?MODULE, l, [NS, MF]), % start a child
gen_tcp:controlling_process(NS, Pid), % give child the socket
Pid ! go_ahead, % synchronize with child
g_loop(S, MF).
%% ----------------------------------------------------------------------
l(S, {UMod, UFun}) ->
process_flag(trap_exit, true),
receive
go_ahead -> % wait for synchronization,
inet:setopts(S, [{active, true}]) % before we activate socket
end,
gen_tcp:send(S, "\nWelcome to Erlang!\n\n"), % could implement login here
U = spawn_link(UMod, UFun, [self()]), % start user process
ll(S, U).
%%
%% Child loop, passes the data between the user process and the socket.
%%
ll(S, U) ->
receive
{tcp, S, Bytes} ->
U ! {self(), {data, Bytes}},
ll(S, U);
{tcp_closed, S} ->
io:format("getty:ll(~p, ~p) socket closed~n", [S, U]),
exit(closed);
{tcp_error, S, Reason} ->
io:format("getty:ll(~p, ~p) socket error ~p~n", [S, U, Reason]),
exit(Reason);
{U, {command, Bytes}} ->
gen_tcp:send(S, Bytes),
ll(S, U);
{'EXIT', U, Why} ->
io:format("getty:ll(~p, ~p) user died ~p~n", [S, U, Why]),
gen_tcp:close(S),
exit(Why);
Other ->
io:format("getty:ll(~p, ~p) got msg ~p~n", [S, U, Other]),
ll(S, U)
end.
This program is an example of a TCP server that waits for a TCP connection on a given port (default 7788). When a connection is established the port is used as a remote Erlang session.
Be aware that this of course gives anyone access to your system, it is only intended as an example!
To start the program:
1> getty:start(). <0.31.0>
This sets up client that listens to port 7788.
We now move to another machine in the network and try to connect to this port
> telnet gordons 7788 Trying 150.236.14.77... Connected to gordons. Escape character is '^]'. Welcome to Erlang! Eshell V4.7.3 (abort with ^G) 1>
Translated from previous site /examples/small_examples/
Tags: [ small_examples ]
