elixirgen-tcp

Elixir gen_tcp.recv not receiving data on unit test when actual telnet clients work


I have a working telnet server that I am trying to create a unit test for. Server works fine with a telnet client, and is expected to send a prompt as soon as connection is made. Send on the same socket works fine. But, the TCP client from the unit test refuses to receive data and timeout. I am new to Elixir, so, I may be missing something basic.

opts = [:binary, packet: :line, active: false, reuseaddr: true]
{:ok, socket} = :gen_tcp.connect('127.0.0.1', 4040, opts)
{:ok, date_string} = Date.universal |> DateFormat.format("{ISO}")
IO.puts "Socket #{inspect socket} Created #{date_string}"
case :gen_tcp.recv(socket, 0, 5000) do
    {:ok, data} -> IO.puts "Recevied data is #{data}"
    {:error, reason} -> IO.puts "Error: Test Setup: First Receive: Reason: #{reason}"
end

I get the following output

Socket #Port<0.5758> Created 2015-12-12T01:36:08.248+0000
Error: Test Setup: First Receive: Reason: timeout

It would help if someone can shed some light on what an Elixir novice is doing wrong


Solution

  • Your bug may come from the use of the packet: :line option. As you may know, this option makes it so that packets on the socket aren't "considered" (e.g., they're not sent as messages if :active is true and they're not returned by :gen_tcp.recv/2-3 if :active is false) until there's a newline.

    This means that if your TCP server sends "foo" down the socket, :gen_tcp.recv will not return it as it's not a "line". Sending "foo/n" gets picked up by :gen_tcp.recv instead.

    Check your server and that it's sending a newline-terminated packet, as that is probably the cause (I can't see anything else wrong with your code :)).