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
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
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’. ![]()
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. ![]()
OvermindDL1
That will be perfect ‘if’ you prepend the 4 integer bytes of the size of the content to your json data. ![]()
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. ![]()
But according to the link, you’ll use the php pack function/2 (probably the ‘N’ option I think). ![]()
Last Post!
robinmonjo
Thank you very much !! Indeed I used packet: :line at the beginning and forgot to change it in the connect options ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #hex
- #security









