Ciboulette

Ciboulette

Gen:tcp socket maximum number of bytes/characters possible to receive

Hey Elixir community,

I have a question, i’m building a communication between php and elixir via socket. I can’t manage to received string bigger than 1460 characters… Every string bigger than this is troncated and send after. Are-there any options to get over this ? thank you very much.

I’m using socket function on the PHP side. Elixir is the socket server and php, the client.

Most Liked

OvermindDL1

OvermindDL1

Heh, I’ve written a LOT of TCP and UDP (and SCTP) protocols over the past 25 years, many in erlang itself, so I like to help when I can. ^.^

OvermindDL1

OvermindDL1

I’m surprised you don’t want to receive it as binaries. ^.^

So there is no format to the packets at all? This sounds like your problem. Remember that TCP is a streaming protocol, you need to have something formatted on the line. Traditionally you have a 1/2/4 byte header of an integer specifing the size of this ‘chunk’ of data, but by putting ‘0’ here that means you will have to do all of the filtering and chunking yourself manually.

Here you are encoding json and sending it to the socket, but you are not saying what ‘size’ it is or anything of the sort. I’d recommend either putting a 4-byte integral size header at the front of it or making sure the json is a single line only (replace newlines in string with \n as per the json standard and remove all formatting newlines) and separate chunks with newlines, the {:packet, :line} option to :gen_tcp can parse those out for you.

If however you want to just dump json to the socket then know that you will receive it in MTU chunks and you will need to combine them and do your own chunking manually, not hard to do though:

You would change this up, receive the data and try to parse the json, if the json fails to parse then put it in an argument and recv again, then append that to the first and try to parse again, repeat until the parse does not fail. Once the parse passes then take any remaining data and put it in that holding argument (remember, you might get multiple json’s in a single packet!!).

However, none of that is necessary if you delinate the tcp chunks properly, like either via an integer header (always the easiest in my opinion) or breaking up on ‘lines’. :slight_smile:

You can do the ‘header’ via changing the packet argument in elixir to {:packet, 4} and doing something like this in PHP (I don’t remember the actual functions so replace them with what they actually are):

$json = json_encode($response);
$json_size = str_bytelength($json);
$host = "127.0.0.1";
$port = 4040;
$socket = socket_create(AF_INET6, SOCK_STREAM, SOL_TCP);
$connection = socket_connect($socket, $host, $port);
socket_write_integer_32bit($socket, $json_size);
socket_write($socket, $json);

Or whatever the right php commands for that is…

Or use {:packet, :line} and make sure the json is a single line and append a newline at the end of each write of the json. :slight_smile:

OvermindDL1

OvermindDL1

That will be perfect ‘if’ you prepend the 4 integer bytes of the size of the content to your json data. :slight_smile:

I found this to help: http://stackoverflow.com/questions/9742449/sending-sockets-data-with-a-leading-length-value

Do note it must be in network-byte order, so if the length seems wrong (as in you may not receive anything) swap the bytes, it must be in network-byte order. :slight_smile:

But according to the link, you’ll use the php pack function/2 (probably the ‘N’ option I think). :slight_smile:

Last Post!

robinmonjo

robinmonjo

Thank you very much !! Indeed I used packet: :line at the beginning and forgot to change it in the connect options :blush:

Where Next?

Popular in Questions Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
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