procket/examples/sendmsg_recvmsg_echo.erl 動かしてみた
結果から書くと、動いた?となる。
まず、自身の現時点の知識だと、何故動いているのか、理解していない。
だから、ここで、理屈を書く事はできない。
あくまでも、動いたソースの保存として書いておく。
将来何かで実装するときは、こう書かないかも知れない。
-module(sample). -export([start/0]). -define(PORT, 8854). -define(SIZEOF_SOCKADDR, sizeof(sockaddr)). start() -> {ok, FD} = procket:socket(inet, dgram, udp), io:format("SIZEOF_SOCKEADDR: ~p~n", [?SIZEOF_SOCKADDR]), ok = procket:setsockopt(FD, 'SOL_SOCKET', 'SO_REUSEPORT', <<1:32>>), Family = procket:family(inet), io:format("inet family ~p~n", [Family]), SA = <<(procket:sockaddr_common(inet, 16)):2/bytes, ?PORT:16/integer-unsigned-big, 192, 168, 0, 1, 0:64>>, io:format("SA: ~p~n", [SA]), ok = procket:bind(FD, SA), loop(FD). loop(FD) -> %% recv a packet up to 512 bytes long, along with 512 bytes of control %% data case procket:recvmsg(FD, 512, 0, 512, ?SIZEOF_SOCKADDR) of {error, eagain} -> loop(FD); {ok, Buf, Flags, CtrlData, From} -> io:format("Buffer ~p, From ~p, Ctrldata ~p Flags ~p~n", [Buf, From, CtrlData, Flags]), %% echo the packet back, but set the destination address to the %% 'from' of the previous packet, and send the previous message's %% control data so that the source address is set to the %% destination address of the previous packet ok = procket:sendmsg(FD, Buf, 0, CtrlData, From), loop(FD) end. sizeof(sockaddr) -> case os:type() of {unix,sunos} -> 32; {unix,_} -> 28 end.
検索しまくっていろいろブックマークをしまくったけど、大半、知識不足で理解できなかった_| ̄|○
https://github.com/msantos/procket/issues/27
どうも、procketの作者さん自身が答えてくれているらしいが、IP4での接続周りは、これで解消できました。
あとは、あんまり弄ってません。でも、2日掛かりました。
さて、自分が分かってない部分。
SAの変数で扱っている関数、procket:sockaddr_common、0:64
recvmsg, sendmsgの詳しい動き、sockaddrとかいうアトムとか・・・
'SOL_SOCKET', 'SO_REUSEPORT'とか、ちんぷんかんぷん。
http://umezawa.dyndns.info/wordpress/?p=2609
より、ヒントをもらって、書いたけど、分かってないです。
(´ヘ`;)ウーム…情けない。
TCP周りは、ちゃんと勉強しないと駄目ですな。