Reputation: 133
I'm making a multichat application and here is the code. In this application I made a server and here is the code :
defmodule Multichat.Server do
require Logger
def accept(port) do
{:ok, socket} = :gen_tcp.listen(port, [:binary, packet: :line, active: true, reuseaddr: true])
Logger.info "Accepting connections on port #{port}"
loop_acceptor(socket)
end
defp loop_acceptor(socket) do
{:ok, client} = :gen_tcp.accept(socket)
{:ok, pid} = DynamicSupervisor.start_child(Multichat.Server.ConnectionSupervisor, {Multichat.ClientConnection, client})
:ok = :gen_tcp.controlling_process(client, pid)
loop_acceptor(socket)
end
end
you can see in the code there is a client part :
defmodule Multichat.ClientConnection do
use GenServer
def start_link(socket), do: GenServer.start_link(__MODULE__, socket)
def init(init_arg) do
{:ok, init_arg}
end
def handle_call({:send, message}, _from, socket) do
:gen_tcp.send(socket, message)
{:reply, :ok, socket}
end
def handle_info({:tcp, _socket, message}, socket) do
for {_, pid, _, _} <- DynamicSupervisor.which_children(Multichat.Server.ConnectionSupervisor) do
if pid != self() do
GenServer.call(pid, {:send, message})
end
end
{:noreply, socket}
end
end
I want when I start a node on a port, the other node can't but connect on another one. How is that possible ?
Upvotes: 1
Views: 69
Reputation: 3509
In linux, listening sockets are bound to any of the device's IP or all of them (1), usually the default being listening in all of them (the 0.0.0.0
ip).
Once a process is listening in one ip:port
, no other socket is able to listen in the same ip:port
(2)
(1) This is not entirely true, because you have network namespaces and the IP_FREEBIND option. (2) Again, not entirely true, you have the SO_REUSEPORT socket option.
So, in this case you have several options:
127.0.0.1
and 127.0.0.2
Socket options are explained here
In Erlang, it seems that the relatively new low-level socket API has the reuseport
option available, whereas, from the inet documentation (gen_tcp), it seems that SO_REUSEPORT
is only available as a raw
option.
Upvotes: 1