fixupj
This commit is contained in:
@@ -1,41 +0,0 @@
|
|||||||
defmodule AlterProxy do
|
|
||||||
def start(port) do
|
|
||||||
# 監聽端口
|
|
||||||
{:ok, listen_socket} =
|
|
||||||
:gen_tcp.listen(port, [
|
|
||||||
:binary,
|
|
||||||
packet: :line,
|
|
||||||
reuseaddr: true,
|
|
||||||
active: false,
|
|
||||||
backlog: 100
|
|
||||||
])
|
|
||||||
|
|
||||||
spawn(__MODULE__, :accept_loop, [listen_socket])
|
|
||||||
listen_socket
|
|
||||||
end
|
|
||||||
|
|
||||||
def accept_loop(listen_socket) do
|
|
||||||
case :gen_tcp.accept(listen_socket) do
|
|
||||||
{:ok, socket} ->
|
|
||||||
spawn(__MODULE__, :handle_client, [socket])
|
|
||||||
accept_loop(listen_socket)
|
|
||||||
|
|
||||||
{:error, reason} ->
|
|
||||||
IO.puts("接受連接失敗: #{reason}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_client(socket) do
|
|
||||||
# 接收數據
|
|
||||||
case :gen_tcp.recv(socket, 0) do
|
|
||||||
{:ok, data} ->
|
|
||||||
IO.puts("收到: #{data}")
|
|
||||||
:gen_tcp.send(socket, "Echo: #{data}")
|
|
||||||
# 繼續接收
|
|
||||||
handle_client(socket)
|
|
||||||
|
|
||||||
{:error, :closed} ->
|
|
||||||
IO.puts("客戶端斷開連接")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,33 +1,21 @@
|
|||||||
defmodule Broker do
|
defmodule Broker do
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
def init({protocol, port, to_host, to_port}) do
|
def start_link({:tcp, port, to_host, to_port}) do
|
||||||
|
GenServer.start_link(__MODULE__, {:tcp, port, to_host, to_port})
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def init({:tcp, port, to_host, to_port}) do
|
||||||
{:ok, listen_socket} =
|
{:ok, listen_socket} =
|
||||||
:gen_tcp.listen(port, [
|
:gen_tcp.listen(port, [
|
||||||
:binary,
|
:binary,
|
||||||
reuseaddr: true,
|
reuseaddr: true,
|
||||||
active: false,
|
active: true,
|
||||||
backlog: 100
|
backlog: 100
|
||||||
])
|
])
|
||||||
|
|
||||||
{:ok,
|
TcpWatcher.start_link({to_host, to_port, listen_socket})
|
||||||
%{
|
{:ok, {:tcp, port, to_host, to_port, listen_socket}}
|
||||||
protocol: protocol,
|
|
||||||
port: port,
|
|
||||||
to_host: to_host,
|
|
||||||
to_port: to_port,
|
|
||||||
listen_socket: listen_socket
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def accept_loop(listen_socket) do
|
|
||||||
case :gen_tcp.accept(listen_socket) do
|
|
||||||
{:ok, socket} ->
|
|
||||||
spawn(__MODULE__, :handle_client, [socket])
|
|
||||||
accept_loop(listen_socket)
|
|
||||||
|
|
||||||
{:error, reason} ->
|
|
||||||
IO.puts("接受連接失敗: #{reason}")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,8 +10,12 @@ defmodule Manager do
|
|||||||
DynamicSupervisor.init(strategy: :one_for_one)
|
DynamicSupervisor.init(strategy: :one_for_one)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_broker(port) do
|
def create_broker(protocol, port, to_host, to_port) do
|
||||||
spec = {Broker, port}
|
spec = {Broker, {protocol, port, to_host, to_port}}
|
||||||
DynamicSupervisor.start_child(__MODULE__, spec)
|
DynamicSupervisor.start_child(__MODULE__, spec)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def list_brokers() do
|
||||||
|
DynamicSupervisor.which_children(__MODULE__)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
defmodule TcpHandler do
|
|
||||||
def start(port) do
|
|
||||||
# 監聽端口
|
|
||||||
{:ok, listen_socket} =
|
|
||||||
:gen_tcp.listen(port, [
|
|
||||||
:binary,
|
|
||||||
packet: :line,
|
|
||||||
reuseaddr: true,
|
|
||||||
active: false,
|
|
||||||
backlog: 100
|
|
||||||
])
|
|
||||||
|
|
||||||
accept_loop(listen_socket)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp accept_loop(listen_socket) do
|
|
||||||
case :gen_tcp.accept(listen_socket) do
|
|
||||||
{:ok, socket} ->
|
|
||||||
spawn(__MODULE__, :handle_client, [socket])
|
|
||||||
accept_loop(listen_socket)
|
|
||||||
|
|
||||||
{:error, reason} ->
|
|
||||||
IO.puts("接受連接失敗: #{reason}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_client(socket) do
|
|
||||||
# 接收數據
|
|
||||||
case :gen_tcp.recv(socket, 0) do
|
|
||||||
{:ok, data} ->
|
|
||||||
IO.puts("收到: #{data}")
|
|
||||||
:gen_tcp.send(socket, "Echo: #{data}")
|
|
||||||
# 繼續接收
|
|
||||||
handle_client(socket)
|
|
||||||
|
|
||||||
{:error, :closed} ->
|
|
||||||
IO.puts("客戶端斷開連接")
|
|
||||||
|
|
||||||
{:error, reason} ->
|
|
||||||
IO.puts("接收數據失敗: #{reason}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
28
lib/tcp_proxy.ex
Normal file
28
lib/tcp_proxy.ex
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
defmodule TcpProxy do
|
||||||
|
use GenServer
|
||||||
|
|
||||||
|
def start_link({watch_pid, to_host, to_port}) do
|
||||||
|
GenServer.start_link(__MODULE__, {watch_pid, to_host, to_port})
|
||||||
|
end
|
||||||
|
|
||||||
|
def init({watch_pid, to_host, to_port}) do
|
||||||
|
{:ok, socket} =
|
||||||
|
:gen_tcp.connect(String.to_charlist(to_host), to_port, [:binary, active: true])
|
||||||
|
|
||||||
|
{:ok, {watch_pid, socket}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info({:tcp, _socket, data}, {watch_pid, _socket} = state) do
|
||||||
|
send(watch_pid, {:send, data})
|
||||||
|
{:noreply, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info({:send, data}, {watch_pid, socket} = state) do
|
||||||
|
:gen_tcp.send(socket, data)
|
||||||
|
{:noreply, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info({:tcp_closed, _port}, state) do
|
||||||
|
{:stop, :normal, state}
|
||||||
|
end
|
||||||
|
end
|
||||||
35
lib/tcp_watcher.ex
Normal file
35
lib/tcp_watcher.ex
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
defmodule TcpWatcher do
|
||||||
|
use GenServer
|
||||||
|
|
||||||
|
def start_link({to_host, to_port, listen_socket}) do
|
||||||
|
GenServer.start_link(__MODULE__, {to_host, to_port, listen_socket})
|
||||||
|
end
|
||||||
|
|
||||||
|
def init({to_host, to_port, listen_socket}) do
|
||||||
|
{:ok, {to_host, to_port, listen_socket}, {:continue, :accept}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_continue(:accept, {to_host, to_port, listen_socket} = _state) do
|
||||||
|
{:ok, socket} = :gen_tcp.accept(listen_socket)
|
||||||
|
start_link({to_host, to_port, listen_socket})
|
||||||
|
{:ok, proxy_id} = TcpProxy.start_link({self(), to_host, to_port})
|
||||||
|
{:noreply, {to_host, to_port, listen_socket, socket, proxy_id}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info({:tcp_closed, _socket}, state) do
|
||||||
|
{:stop, :normal, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info(
|
||||||
|
{:tcp, _socket, data},
|
||||||
|
{_to_host, _to_port, _listen_socket, _socket, proxy_id} = state
|
||||||
|
) do
|
||||||
|
send(proxy_id, {:send, data})
|
||||||
|
{:noreply, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info({:send, data}, {_to_host, _to_port, _listen_socket, socket, _proxy_id} = state) do
|
||||||
|
:gen_tcp.send(socket, data)
|
||||||
|
{:noreply, state}
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user