【问题标题】:How to disable two nodes to connect on the same port?如何禁用两个节点在同一个端口上连接?
【发布时间】:2020-12-29 03:18:22
【问题描述】:

我正在制作一个多聊天应用程序,这里是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

你可以在代码中看到有一个客户端部分:

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

我希望当我在一个端口上启动一个节点时,另一个节点只能连接另一个节点。这怎么可能?

【问题讨论】:

    标签: erlang elixir gen-tcp


    【解决方案1】:

    在 linux 中,侦听套接字绑定到设备的任何 IP 或全部 (1),通常默认情况下正在侦听所有这些 (0.0.0.0 ip)。 一旦一个进程在一个ip:port 中侦听,其他套接字就不能在同一个ip:port 中侦听 (2)

    (1) 这并不完全正确,因为您有网络命名空间和 IP_FREEBIND 选项。 (2) 同样,不完全正确,您有 SO_REUSEPORT 套接字选项。

    因此,在这种情况下,您有多种选择:

    1. 为要在本地启动的每个节点设置不同的端口,例如,使用环境变量
    2. 在开发过程中为每个节点监听不同的IP,例如127.0.0.1127.0.0.2
    3. 在监听套接字中设置 SO_REUSEPORT 选项
    4. 使用 docker 或其他容器/命名空间技术能够在不同的网络命名空间中启动不同的节点。

    套接字选项解释here
    在 Erlang 中,相对较新的 low-level socket API 似乎有 reuseport 选项可用,而从 inet documentation (gen_tcp) 看来,SO_REUSEPORT 似乎只能作为 raw 选项使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-27
      • 2021-02-03
      • 1970-01-01
      • 2011-04-13
      • 2012-03-07
      • 2011-07-05
      • 2011-03-27
      • 1970-01-01
      相关资源
      最近更新 更多