jononomo

jononomo

I can connect using :gen_tcp, but I can't send/receive data - what is wrong with this implementation?

All I want it to do is emulate the following netcat TCP command, which is working properly from my command line:

$ echo "|c country_US" | nc 10.247.4.104 26542
0.500000        <-- response

To accomplish this I have an Elixir module that uses GenServer and :gen_tcp as follows (it has a few extra IO.puts and IO.inspect calls so I can watch progress):

defmodule VowpalWabbex do
    use GenServer

    def predict(pid, client_data) do
        GenServer.call(pid, {:predict, client_data})
    end

    @initial_state %{socket: nil}

    def start_link do
        GenServer.start_link(__MODULE__, @initial_state)
    end

    def init(state) do
        IO.puts "VowpalWabbex - init..."
        opts = [:binary, :inet, active: false, packet: :line]
        {:ok, socket} = :gen_tcp.connect({10, 247, 4, 104}, 26542, opts)
        IO.inspect socket
        {:ok, %{state | socket: socket}}
    end

    def handle_call({:predict_adx_inflation, client_data}, _from, %{socket: socket} = state) do
        IO.inspect client_data
        IO.inspect socket
        :ok = :gen_tcp.send(socket, client_data)
        IO.puts :ok
        {:ok, msg} = :gen_tcp.recv(socket, 0)
        {:reply, msg, state}
    end

end

I would use this module from within IEX as follows:

$ iex -S mix
Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Compiling 1 file (.ex)

iex(1)> {:ok, pid} = VowpalWabbex.start_link
VowpalWabbex - init...
#Port<0.6774>
{:ok, #PID<0.238.0>}

iex(2)> VowpalWabbex.predict(pid, "|c country_US")
"|c country_US"
#Port<0.6774>
ok

** (exit) exited in: GenServer.call(#PID<0.238.0>, {:predict, "data"}, 5000)
** (EXIT) time out

So apparently I get an “ok” response when I send the data, but then the I never get a response and instead I time out in a couple of seconds.

Am I doing something wrong in how I’m trying to receive the response?

Thanks much!

Marked As Solved

NobbZ

NobbZ

edit

Please read this before my original post below:

echo in bash always appends a \n (unless told not to do), so, yes, you might need to send it as well.

If that does not work, please consider my original post below.


original post

Your dump only shows header information. I usually dump into a file using -w option. After that I look at the dumps using wireshark. You can inspect package contents then.

Also just removing packet: :line will make things about worse, since the default is packet: 4 as far as I remember, which means that erlang will parse the first 4 byte as unsigned integer and wait for that amount of bytes until it hands the message over to you.

If I were you, I’d try to use packet: :raw for at least a try.

Also Liked

NobbZ

NobbZ

It’s not a wish, its just a warning :wink:

I had to go through similar behaviour as :raw has in a language that didn’t gave me a choice. Even worse I had to make sure I have already allocated buffers large enough to hold the data. And I had to chunk it by my self when I knew previously that my RAM (4 MiB) won’t be enough to process everything at once…

But I do hope, that I do not need to do embedded networking again :wink:

NobbZ

NobbZ

Do not keep :raw unless you have to! It will break your neck if you have a linebased protocol and many concurrent packages to receive!

NobbZ

NobbZ

Does your server send a \n at the end of the package or is it just a fixed with string? That bunch of zeros at the end makes me suspicious…

And again, have you checked using tcpdump and friends what is really sent over the wire?

Last Post!

NobbZ

NobbZ

It’s not a wish, its just a warning :wink:

I had to go through similar behaviour as :raw has in a language that didn’t gave me a choice. Even worse I had to make sure I have already allocated buffers large enough to hold the data. And I had to chunk it by my self when I knew previously that my RAM (4 MiB) won’t be enough to process everything at once…

But I do hope, that I do not need to do embedded networking again :wink:

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New

Other popular topics Top

Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement