3

I have the following TCP server written in Elixir utilizing the gen_tcp OTP module:

defmodule Test do
  def server() do
    {:ok, listen_sock} = :gen_tcp.listen(43594, [{:active, true}, :binary])
    {:ok, accept_sock} = :gen_tcp.accept(listen_sock)
    spawn(fn() -> poll(accept_sock) end)
  end

  defp poll(sock) do
    case :gen_tcp.recv(sock, 0, 20) do
      {:ok, data} ->
          IO.puts "#{data}"
          poll(sock)
      {:error, :closed} -> :ok
    end
  end
end

Test.server

As soon as I use telnet to connect to the server, it disconnects. Any idea as to what's going on?

Ismael Abreu
  • 16,443
  • 6
  • 61
  • 75
leaf
  • 95
  • 5
  • When the process which opened the listen socket with `:gen_tcp.listen` dies then that socket dies as well as all the sockets open through the list socket. – rvirding Apr 22 '14 at 08:48

1 Answers1

4

I would assume it's because server() is returning after spawn() is called and your application exits normally. I would write it like so:

defmodule Test do
  def server() do
    {:ok, listen_sock} = :gen_tcp.listen(43594, [{:active, true}, :binary])
    {:ok, accept_sock} = :gen_tcp.accept(listen_sock)
    poll(accept_sock)
  end

  defp poll(sock) do
    case :gen_tcp.recv(sock, 0, 20) do
      {:ok, data} ->
          IO.puts "#{data}"
          poll(sock)
      {:error, :closed} -> :ok
    end
  end
end

Test.server

I haven't tested the above code, but that should fix your problem.

bitwalker
  • 9,061
  • 1
  • 35
  • 27
  • 2
    Yup, that will likely be the issue. Another option is to pass the `--no-halt` option: `elixir --no-halt test_server.exs` – José Valim Apr 20 '14 at 11:09