Ciboulette

Ciboulette

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.

Showing Posts 1 to 10

idi527

idi527

Isn’t it the maximum segment size? I would guess there is no way around that.

Ciboulette

Ciboulette OP

Damn, ok …

idi527

idi527

Wikipedia says [0]

For most computer users, the MSS option is established by the operating system.

So maybe you can change it on your OS?

[0] Maximum segment size - Wikipedia

xlphs

xlphs

Use UDP, that will automatically give you packets as large as 65,507 bytes. You can also try IPC or unix domain socket, which has even greater message limit.
If you use TCP, you should implement message framing logic, which complicates logic on the both ends.
Finally, you can always use Redis pub/sub or similar.

Ciboulette

Ciboulette OP

thanks a lot for your answer, i will look into these

OvermindDL1

OvermindDL1

Uhh, I’m curious about a lot of the responses here…

TCP is a streaming protocol, it already implements everything suggested here (not always efficiently, but it works), and your use case as you described it in your first post should absolutely work.

Can you make a minimal reproducable test-case for your php sender and elixir receiver, I can take a look at the code and test it and see what is going on.

From an initial guess (due to the complete lack of code in the post, hint hint ^.^) I’m guessing the receive options are not set as you expect and are processing the information as it arrives instead of as complete chunks. :slight_smile:

Ciboulette

Ciboulette OP

defmodule TaskyRabbit.Socket do
  use GenServer


  defmodule State do
     defstruct port: nil, lsock: nil, socket: nil
  end
  #######
  # API #
  #######

  def start_link(port) do
    GenServer.start_link(__MODULE__, port, name: __MODULE__)
  end

  def init(port) do
    IO.puts(port)
    current = self()
    tcp_options = [:list, {:packet, 0}, {:active, false}, {:reuseaddr, true}, {:packet_size, 50}]
    # tcp_options = [:binary, packet: 0, active: false, reuseaddr: true]
    {:ok, l_socket} = :gen_tcp.listen(port, tcp_options)
    send(current, :accept)
    {:ok, %State{port: port, socket: l_socket}}
  end



  def handle_info(:accept, state = %{socket: socket}) do
    do_listen(socket)
    {:noreply, state}
  end


  defp do_listen(l_socket) do
    {:ok, socket} = :gen_tcp.accept(l_socket)

    spawn(fn() -> do_server(socket) end)

    do_listen(l_socket)
  end


  defp do_server(socket, array \\ []) do
    case :gen_tcp.recv(socket, 0) do
      { :ok, data } ->
        IO.inspect (data), label: "received"
        # TaskyRabbit.tcp_rbmq(data)
      { :error, :closed } ->
        IO.inspect "closed"
        :ok
    end
  end
end
Ciboulette

Ciboulette OP

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

the PHP code

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:

Ciboulette

Ciboulette OP

Ok so on elixir my options must be tcp_options = [:binary, {:packet, 4}, :line, active: false, reuseaddr: true] ?

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New
thiagogsr
** (ArgumentError) expected :max_attempts to be a positive integer, got: {:@, [line: 10, column: 19], [{:max_attempts, [line: 10, column:...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews