-module(adder).
-export([client/2, client/3, server/1]).

client(Port, List) ->
  client("localhost", Port, List).
client(Host, Port, List) ->
  {ok, Sock} = gen_tcp:connect(Host, Port, [binary]),
  [ok = gen_tcp:send(Sock, <<I:32>>) || I <- List],
  gen_tcp:shutdown(Sock, write),   
  receive {tcp, Sock, <<J:32>>} ->
    receive {tcp_closed, Sock} -> ok = gen_tcp:close(Sock), J end
  end.

server(Port) ->
  {ok, LSock} = gen_tcp:listen(Port, [{exit_on_close, false}, binary]),
  acceptor(LSock, 0).

acceptor(LSock, Sum) ->
  {ok, Sock} = gen_tcp:accept(LSock),
  io:format("new client~n", []),
  NewSum = serve(Sock, Sum, <<>>),
  acceptor(LSock, NewSum).

serve(Sock, Sum, Buffer) ->
  receive
    {tcp, _, Data} ->
      {NewSum, NewBuffer} = handle(Sum, <<Buffer/binary, Data/binary>>),
      serve(Sock, NewSum, NewBuffer);
    {tcp_closed, Sock} ->
      io:format("client disconnected~n", []),
      ok = gen_tcp:send(Sock, <<Sum:32>>),
      ok = gen_tcp:close(Sock),
      Sum;
    {tcp_error, Sock, _} ->
      io:format("tcp error~n", []),
      Sum
  end.

handle(Sum, <<I:32, R/binary>>) -> handle(I + Sum, R);
handle(Sum, Buf) -> {Sum, Buf}.

