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?

OvermindDL1

OvermindDL1

Especially this because you are doing packet: :line so every single ‘statement’ needs to be terminated with a \n from the remote connection.

jononomo

jononomo

Ok, I think the problem is solved!

I’ll leave packet: :raw, since it isn’t breaking anything, but it looks like everything works as expected when I appended a newline to the data that I sent.

You guys have both been helpful beyond imagination to me. I’m sincerely grateful for your thoughtful engagement with my problem.

Where Next?

Popular in Questions Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
jc00ke
Expanding on this topic: https://forum.elixirforum.net/t/map-typespec-question/19217 Let’s say I have a map with required and optional k...
New

Other popular topics Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement