2017-07-11 13 views
1

私はエリクサーと奇妙な実験をしています。 (これは奇妙ではないかもしれませんが、これまでにこれをしていませんでした)実行中のTCPサーバから新しいTCPサーバを起動できますか?

入力に基づいて他のTCPサーバーを起動できるTCPサーバーを設定しようとしています。可能なことを見出そうとするだけで、これはどこにでも出ていくわけではありません。私はTCPに精通していません。

最初のサーバは罰金を開始するが、私は(Telnet経由)最初のサーバに「PORT 9000」のようなものを入力しようとすると、私のコードは、このエラーがスローされます。ここでは

FunctionClauseError) no function clause matching in :inet_tcp.getserv/1 
    (kernel) inet_tcp.erl:55: :inet_tcp.getserv("9000") 
    (kernel) gen_tcp.erl:190: :gen_tcp.listen/2 
    (gen_tcp) lib/tcp_server.ex:11: TcpServer.init/1 
    (stdlib) gen_server.erl:328: :gen_server.init_it/6 
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3 

はコードです:

defmodule TcpServer do 
    use GenServer 

    def start_link(port) do 
    ip = Application.get_env :tcp_server, :ip, {127,0,0,1} 
    port = Application.get_env :tcp_server, :port, port 
    GenServer.start_link(__MODULE__,[ip,port],[]) 
    end 

    def init [ip,port] do 
    {:ok, listen_socket} = :gen_tcp.listen(port,[:binary, {:packet, 0}, {:active, true}, {:ip, ip}]) 
    {:ok, socket} = :gen_tcp.accept listen_socket 
    {:ok, %{ip: ip, port: port, socket: socket}} 
    end 

    def handle_info({ :tcp, socket, packet }, state) do 
    # Expects something like "PORT 3456" 
    if packet =~ "PORT" do 
     port_number = String.slice(packet, -5..-2) 
     TcpServer.start_link(port_number) 
     :gen_tcp.send socket, "Started new server on port #{port_number}" 
    else 
     :gen_tcp.send socket, "Message received... \n" 
    end 
    IO.inspect packet, label: "incoming packet" 
    {:noreply, state} 
    end 

    def handle_info({:tcp_closed, socket}, state) do 
    IO.inspect "Socket has been closed" 
    {:noreply, state} 
    end 

    def handle_info({:tcp_error, socket, reason}, state) do 
    IO.inspect socket,label: "connection closed dut to #{reason}" 
    {:noreply, state} 
    end 
end 

私は何か間違っているのですか、これは私が気付いていない何らかの理由でうまくいかないでしょうか?

(コードはほとんどhttps://medium.com/blackode/quick-easy-tcp-genserver-with-elixir-and-erlang-10189b25e221からプル)

+1

これはコメントとして投稿しています: '' PORT ''プレフィックスを' String.slice'の代わりにパターンマッチングで削除することもできます: 'def handle_info({:tcp、socket、 "ポート" <ポート}、状態) '。 – Dogbert

+0

これは非常に便利です。ありがとう! –

答えて

0

はErlangのドキュメントでこれを見つけた:

{port_number, _extra} = Integer.parse(String.slice(packet, -5..-2)) 
0

あなたが渡す前に整数にport_numberを変換する必要があります。

getserv(Port) when is_integer(Port) -> {ok, Port}; 

が、私はこれを必要なように見えますどんなinet関数にも。
SockErl

関連する問題