我正在用Elixir进行一种奇怪的实验。 (也许这并不奇怪,但我之前没有这样做过。)
我正在尝试设置一个可以根据某些输入触发其他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)
答案 0 :(得分:0)
在Erlang文档中找到了这个:
getserv(Port) when is_integer(Port) -> {ok, Port};
看起来我需要这个:
{port_number, _extra} = Integer.parse(String.slice(packet, -5..-2))
答案 1 :(得分:0)
在传递给任何port_number
函数之前,您应该将inet
转换为整数
我建议使用SockErl