クライアント (NAT の背後) にパケットを専用サーバーに送信させようとしています。
これが私のコードです:
-module(udp_test).
-export([start_client/3, listen/1, send/4, start_listen/1]).
start_client(Host, Port, Packet) ->
{ok, Socket} = gen_udp:open(0, [{active, true}, binary]),
io:format("client opened socket=~p~n",[Socket]),
spawn(?MODULE, send, [Socket, Host, Port, Packet]).
start_listen(Port) ->
{ok, Socket} = gen_udp:open(Port, [binary]),
spawn(?MODULE, listen, [Socket]).
listen(Socket) ->
inet:setopts(Socket, [{active, once}]),
receive
{udp, Socket , Host, Port, Bin} ->
gen_udp:send(Socket, Host, Port, "Got Message"),
io:format("server received:~p / ~p~n",[Socket, Bin]),
listen(Socket)
end.
send(Socket, Host, Port, Packet) ->
timer:send_after(1000, tryToSend),
receive
tryToSend ->
io:fwrite("Sending: ~p / to ~p / P: ~p~n", [Packet, Host, Port]),
Val = gen_udp:send(Socket, Host, Port, Packet),
io:fwrite("Value: ~p~n", [Val]),
send(Socket, Host, Port, Packet);
_ ->
io:fwrite("???~n")
end.
専用サーバーでリッスン機能を起動します。
# erl -pa ebin
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:4:4] [async-threads:0] [kernel-poll:false]
Eshell V5.9.1 (abort with ^G)
1> udp_test:listen(4000).
クライアント側で、送信ループを起動します:
$ erl -pa ebin
Erlang R15B (erts-5.9) [source] [smp:2:2] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9 (abort with ^G)
1> udp_test:start_client("ip.of.my.server", 4000, "HELLO !!!").
client opened socket=#Port<0.737>
<0.33.0>
Sending: "HELLO !!!" / to "ip.of.my.server" / P: 4000
Value: ok
Sending: "HELLO !!!" / to "ip.of.my.server" / P: 4000
Value: ok
Sending: "HELLO !!!" / to "ip.of.my.server" / P: 4000
Value: ok
クライアントからのgen_udp :sendはokを返しますが、コンソールに「 server received: "HELLO !!!" 」と出力する必要があるため、サーバーはこれらのパケットを受信していないようです。
なぜこれが機能しないのか、誰もが考えているでしょう。
編集1:
専用サーバーにファイアウォールや iptable が構成されていません。
接続はクライアントとサーバー間の TCP を介して正常に機能しますが、UDP は機能しません。
サーバーとクライアントの両方を同じデバイス (別の erlang ノード) で実行しようとしても、どちらも機能しません。
EDIT 2 : メッセージを受信するたびにソケットを再作成することでループする listen 部分のコードを変更しましたが、それでも機能しません。