{"id":98,"date":"2014-12-07T16:33:05","date_gmt":"2014-12-07T08:33:05","guid":{"rendered":"http:\/\/www.zhuyanbin.com\/?p=98"},"modified":"2014-12-07T16:33:05","modified_gmt":"2014-12-07T08:33:05","slug":"%e5%9f%ba%e4%ba%8eerlang-otp%e6%9e%84%e5%bb%ba%e4%b8%80%e4%b8%aatcp%e6%9c%8d%e5%8a%a1%e5%99%a8","status":"publish","type":"post","link":"https:\/\/www.yanbin888.com\/?p=98","title":{"rendered":"\u57fa\u4e8eErlang OTP\u6784\u5efa\u4e00\u4e2aTCP\u670d\u52a1\u5668"},"content":{"rendered":"<h2><strong>\u5957\u63a5\u5b57\u6a21\u5f0f<\/strong><\/h2>\n<p>\u4e3b\u52a8\u6a21\u5f0f\uff08\u9009\u9879{active, true}\uff09\u4e00\u822c\u8ba9\u4eba\u5f88\u559c\u6b22\uff0c\u975e\u963b\u585e\u6d88\u606f\u63a5\u6536\uff0c\u4f46\u5728\u7cfb\u7edf\u65e0\u6cd5\u5e94\u5bf9\u8d85\u5927\u6d41\u91cf\u8bf7\u6c42\u65f6\uff0c\u5ba2\u6237\u7aef\u53d1\u9001\u7684\u6570\u636e\u5feb\u8fc7\u670d\u52a1\u5668\u53ef\u4ee5\u5904\u7406\u7684\u901f\u5ea6\uff0c\u90a3\u4e48\u7cfb\u7edf\u5c31\u53ef\u80fd\u4f1a\u9020\u6210\u6d88\u606f\u7f13\u51b2\u533a\u88ab\u585e\u6ee1\uff0c\u53ef\u80fd\u51fa\u73b0\u6301\u7eed\u7e41\u5fd9\u7684\u6d41\u91cf\u7684\u6781\u7aef\u60c5\u51b5\u4e0b\uff0c\u7cfb\u7edf\u56e0\u8bf7\u6c42\u800c\u6ea2\u51fa\uff0c\u865a\u62df\u673a\u9020\u6210\u5185\u5b58\u4e0d\u8db3\u7684\u98ce\u9669\u800c\u5d29\u6e83\u3002<\/p>\n<p>\u4f7f\u7528\u88ab\u52a8\u6a21\u5f0f\uff08\u9009\u9879{active, false}\uff09\u7684\u5957\u63a5\u5b57\uff0c\u5e95\u5c42\u7684TCP\u7f13\u51b2\u533a\u53ef\u7528\u4e8e\u6291\u5236\u8bf7\u6c42\uff0c\u5e76\u62d2\u7edd\u5ba2\u6237\u7aef\u7684\u6d88\u606f\uff0c\u5728\u63a5\u6536\u6570\u636e\u7684\u5730\u65b9\u90fd\u4f1a\u8c03\u7528gen_tcp:recv\uff0c\u9020\u6210\u963b\u585e\uff08\u5355\u8fdb\u7a0b\u6a21\u5f0f\u4e0b\u5c31\u53ea\u80fd\u6d88\u6781\u7b49\u5f85\u67d0\u4e00\u4e2a\u5177\u4f53\u7684\u5ba2\u6237\u7aef\u5957\u63a5\u5b57\uff0c\u5f88\u5371\u9669\uff09\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u64cd\u4f5c\u7cfb\u7edf\u53ef\u80fd\u8fd8\u4f1a\u505a\u4e00\u4e9b\u7f13\u5b58\u5141\u8bb8\u5ba2\u6237\u7aef\u673a\u5668\u7ee7\u7eed\u53d1\u9001\u5c11\u91cf\u6570\u636e\uff0c\u7136\u540e\u624d\u4f1a\u5c06\u5176\u963b\u585e\uff0c\u6b64\u65f6Erlang\u5c1a\u672a\u8c03\u7528recv\u51fd\u6570\u3002<\/p>\n<p>\u6df7\u5408\u578b\u6a21\u5f0f\uff08\u534a\u963b\u585e\uff09\uff0c\u4f7f\u7528\u9009\u9879{active, once}\u6253\u5f00\uff0c\u4e3b\u52a8\u4ec5\u9488\u5bf9\u4e00\u4e2a\u6d88\u606f\uff0c\u5728\u63a7\u5236\u8fdb\u7a0b\u53d1\u9001\u5b8c\u4e00\u4e2a\u6570\u636e\u6d88\u606f\u540e\uff0c\u5fc5\u987b\u663e\u793a\u8c03\u7528inet:setopts(Socket, [{active, once}])\u91cd\u65b0\u6fc0\u6d3b\u4ee5\u4fbf\u63a5\u53d7\u4e0b\u4e00\u4e2a\u6d88\u606f\uff08\u5728\u6b64\u4e4b\u524d\uff0c\u7cfb\u7edf\u5904\u4e8e\u963b\u585e\u72b6\u6001\uff09\u3002\u53ef\u89c1\uff0c\u6df7\u5408\u578b\u6a21\u5f0f\u7efc\u5408\u4e86\u4e3b\u52a8\u6a21\u5f0f\u548c\u88ab\u52a8\u6a21\u5f0f\u7684\u4e24\u8005\u4f18\u52bf\uff0c\u53ef\u5b9e\u73b0\u6d41\u91cf\u63a7\u5236\uff0c\u9632\u6b62\u670d\u52a1\u5668\u88ab\u8fc7\u591a\u6d88\u606f\u6df9\u6ca1\u3002<\/p>\n<p>\u4ee5\u4e0bTCP Server\u4ee3\u7801\uff0c\u90fd\u662f\u5efa\u7acb\u5728\u6df7\u5408\u578b\u6a21\u5f0f\uff08\u534a\u963b\u585e\uff09\u57fa\u7840\u4e0a\u3002<\/p>\n<h2><strong>prim_inet\u76f8\u5173\u8bf4\u660e<\/strong><\/h2>\n<p>prim_inet\u6ca1\u6709\u5b98\u65b9\u6587\u6863\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u662f\u5bf9\u5e95\u5c42socket\u7684\u76f4\u63a5\u5305\u88c5\u3002\u6dd8\u5b9d<a href=\"http:\/\/www.yufeng.info\/\" target=\"_blank\">yufeng<\/a>\u8bf4\uff0c\u8fd9\u662fotp\u5185\u90e8\u5b9e\u73b0\u7684\u7ec6\u8282 \u662f\u9488\u5bf9Erlang\u5e93\u5f00\u53d1\u8005\u7684private module\uff0c\u5e95\u5c42\u6a21\u5757\uff0c\u4e0d\u63a8\u8350\u4f7f\u7528\u3002\u4f46\u5728<a href=\"http:\/\/www.trapexit.org\/Building_a_Non-blocking_TCP_server_using_OTP_principles\" target=\"_blank\">Building a Non-blocking TCP server using OTP principles<\/a>\u793a\u8303\u4e2d\u6f14\u793a\u4e86prim_inet\u64cd\u4f5cSocket\u5f02\u6b65\u7279\u6027\u3002<\/p>\n<h2><strong>\u8bbe\u8ba1\u6a21\u5f0f<\/strong><\/h2>\n<p>\u4e00\u822c\u6765\u8bf4\uff0c\u9700\u8981\u4e00\u4e2a\u5355\u72ec\u8fdb\u7a0b\u8fdb\u884c\u5ba2\u6237\u7aef\u5957\u63a5\u5b57\u76d1\u542c\uff0c\u6bcf\u4e00\u4e2a\u5b50\u8fdb\u7a0b\u8fdb\u884c\u5904\u7406\u6765\u81ea\u5177\u4f53\u5ba2\u6237\u7aef\u7684socket\u8bf7\u6c42\u3002<\/p>\n<p>\u5728<a href=\"http:\/\/www.trapexit.org\/Building_a_Non-blocking_TCP_server_using_OTP_principles\" target=\"_blank\">Building a Non-blocking TCP server using OTP principles<\/a>\u793a\u8303\u4e2d\uff0c\u5b50\u8fdb\u7a0b\u4f7f\u7528gen_fsm\u5904\u7406\uff0c\u5f88\u5de7\u5999\u7684\u7ed3\u5408\u72b6\u6001\u673a\u548c\u6d88\u606f\u4e8b\u4ef6\uff0c\u503c\u5f97\u5b66\u4e60\u3002<\/p>\n<p>\u5728<a href=\"http:\/\/20bits.com\/article\/erlang-a-generalized-tcp-server\" target=\"_blank\">Erlang: A Generalized TCP Server<\/a>\u6587\u7ae0\u4e2d\uff0c\u4f5c\u8005\u4e5f\u662f\u4f7f\u7528\u6b64\u6a21\u5f0f\uff0c\u4f46\u5b50\u8fdb\u7a0b\u4e0d\u7b26\u5408OTP\u89c4\u8303\uff0c\u56e0\u6b64\u4e2a\u4eba\u8ba4\u4e3a\u4e0d\u662f\u4e00\u4e2a\u5f88\u597d\u7684\u5b9e\u8df5\u6a21\u5f0f\u3002<\/p>\n<h2><strong>simple_one_for_one<\/strong><\/h2>\n<p>\u7b80\u6613\u7684\u4e00\u5bf9\u4e00\u76d1\u7763\u8fdb\u7a0b\uff0c\u7528\u6765\u521b\u5efa\u4e00\u7ec4\u52a8\u6001\u5b50\u8fdb\u7a0b\u3002\u5bf9\u4e8e\u9700\u8981\u5e76\u53d1\u5904\u7406\u591a\u4e2a\u8bf7\u6c42\u7684\u670d\u52a1\u5668\u8f83\u4e3a\u5408\u9002\u3002\u6bd4\u5982socket \u670d\u52a1\u7aef\u63a5\u53d7\u65b0\u7684\u5ba2\u6237\u7aef\u8fde\u63a5\u8bf7\u6c42\u4ee5\u540e\uff0c\u9700\u8981\u52a8\u6001\u521b\u5efa\u4e00\u4e2a\u65b0\u7684socket\u8fde\u63a5\u5904\u7406\u5b50\u8fdb\u7a0b\u3002\u82e5\u9075\u5b88OTP\u539f\u5219\uff0c\u90a3\u5c31\u662f\u5b50\u76d1\u7763\u8fdb\u7a0b\u3002<\/p>\n<h2><strong>TCP Server\u5b9e\u73b0<\/strong><\/h2>\n<h3><strong>\u57fa\u4e8e\u6807\u51c6API\u7b80\u5355\u5b9e\u73b0<\/strong><\/h3>\n<p>\u4e5f\u662f\u57fa\u4e8e{active, once}\u6a21\u5f0f\uff0c\u4f46\u963b\u585e\u7684\u7b49\u5f85\u4e0b\u4e00\u4e2a\u5ba2\u6237\u7aef\u8fde\u63a5\u7684\u4efb\u52a1\u88ab\u629b\u7ed9\u4e86\u5b50\u76d1\u7763\u8fdb\u7a0b\u3002<\/p>\n<p>\u770b\u4e00\u4e0b\u5165\u53e3tcp_server_app\u5427<\/p>\n<div id=\"gist3945140\" class=\"gist\">\n<div class=\"gist-file\">\n<div class=\"gist-data gist-syntax\">\n<div class=\"file-data\">\n<table class=\"lines highlight\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"line-numbers\"><\/td>\n<td class=\"line-data\">\n<div id=\"file-tcp_server_app-erl-LC1\" class=\"line\">&#8211;<span class=\"pl-k\">module<\/span>(<span class=\"pl-en\">tcp_server_app<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC2\" class=\"line\">&#8211;<span class=\"pl-k\">author<\/span>(<span class=\"pl-c1\">&#8216;yongboy@gmail.com&#8217;<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC3\" class=\"line\">&#8211;<span class=\"pl-k\">behaviour<\/span>(<span class=\"pl-en\">application<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC4\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">start<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">stop<\/span>\/<span class=\"pl-c1\">1<\/span>]).<\/div>\n<div id=\"file-tcp_server_app-erl-LC5\" class=\"line\">&#8211;<span class=\"pl-k\">define<\/span>(<span class=\"pl-en\">DEF_PORT<\/span>, <span class=\"pl-c1\">2222<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC6\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_app-erl-LC7\" class=\"line\"><span class=\"pl-en\">start<\/span>(<span class=\"pl-vo\">_Type<\/span>, <span class=\"pl-vo\">_Args<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC8\" class=\"line\"><span class=\"pl-vo\">Opts<\/span> <span class=\"pl-k\">=<\/span> [<span class=\"pl-c1\">binary<\/span>, {<span class=\"pl-c1\">packet<\/span>, <span class=\"pl-c1\">2<\/span>}, {<span class=\"pl-c1\">reuseaddr<\/span>, <span class=\"pl-c1\">true<\/span>},<\/div>\n<div id=\"file-tcp_server_app-erl-LC9\" class=\"line\">{<span class=\"pl-c1\">keepalive<\/span>, <span class=\"pl-c1\">true<\/span>}, {<span class=\"pl-c1\">backlog<\/span>, <span class=\"pl-c1\">30<\/span>}, {<span class=\"pl-c1\">active<\/span>, <span class=\"pl-c1\">false<\/span>}],<\/div>\n<div id=\"file-tcp_server_app-erl-LC10\" class=\"line\"><span class=\"pl-vo\">ListenPort<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">get_app_env<\/span>(<span class=\"pl-c1\">listen_port<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">DEF_PORT<\/span>),<\/div>\n<div id=\"file-tcp_server_app-erl-LC11\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">LSock<\/span>} <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">listen<\/span>(<span class=\"pl-vo\">ListenPort<\/span>, <span class=\"pl-vo\">Opts<\/span>),<\/div>\n<div id=\"file-tcp_server_app-erl-LC12\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">tcp_server_sup<\/span>:<span class=\"pl-en\">start_link<\/span>(<span class=\"pl-vo\">LSock<\/span>) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC13\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">Pid<\/span>} -&gt;<\/div>\n<div id=\"file-tcp_server_app-erl-LC14\" class=\"line\"><span class=\"pl-en\">tcp_server_sup<\/span>:<span class=\"pl-en\">start_child<\/span>(),<\/div>\n<div id=\"file-tcp_server_app-erl-LC15\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">Pid<\/span>};<\/div>\n<div id=\"file-tcp_server_app-erl-LC16\" class=\"line\"><span class=\"pl-vo\">Other<\/span> -&gt;<\/div>\n<div id=\"file-tcp_server_app-erl-LC17\" class=\"line\">{<span class=\"pl-c1\">error<\/span>, <span class=\"pl-vo\">Other<\/span>}<\/div>\n<div id=\"file-tcp_server_app-erl-LC18\" class=\"line\"><span class=\"pl-k\">end<\/span>.<\/div>\n<div id=\"file-tcp_server_app-erl-LC19\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_app-erl-LC20\" class=\"line\"><span class=\"pl-en\">stop<\/span>(<span class=\"pl-vo\">_S<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC21\" class=\"line\"><span class=\"pl-c1\">ok<\/span>.<\/div>\n<div id=\"file-tcp_server_app-erl-LC22\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_app-erl-LC23\" class=\"line\"><span class=\"pl-en\">get_app_env<\/span>(<span class=\"pl-vo\">Opt<\/span>, <span class=\"pl-vo\">Default<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC24\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">application<\/span>:<span class=\"pl-en\">get_env<\/span>(<span class=\"pl-en\">application<\/span>:<span class=\"pl-en\">get_application<\/span>(), <span class=\"pl-vo\">Opt<\/span>) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC25\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">Val<\/span>} -&gt; <span class=\"pl-vo\">Val<\/span>;<\/div>\n<div id=\"file-tcp_server_app-erl-LC26\" class=\"line\"><span class=\"pl-v\">_<\/span> -&gt;<\/div>\n<div id=\"file-tcp_server_app-erl-LC27\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">init<\/span>:<span class=\"pl-en\">get_argument<\/span>(<span class=\"pl-vo\">Opt<\/span>) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC28\" class=\"line\">[[<span class=\"pl-vo\">Val<\/span> | <span class=\"pl-v\">_<\/span>]] -&gt; <span class=\"pl-vo\">Val<\/span>;<\/div>\n<div id=\"file-tcp_server_app-erl-LC29\" class=\"line\"><span class=\"pl-c1\">error<\/span> -&gt; <span class=\"pl-vo\">Default<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC30\" class=\"line\"><span class=\"pl-k\">end<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC31\" class=\"line\"><span class=\"pl-k\">end<\/span>.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"gist-meta\"><a href=\"https:\/\/gist.github.com\/yongboy\/3945140\/raw\/tcp_server_app.erl\">view raw<\/a><a href=\"https:\/\/gist.github.com\/yongboy\/3945140#file-tcp_server_app-erl\">tcp_server_app.erl<\/a> hosted with \u2764 by <a href=\"https:\/\/github.com\/\">GitHub<\/a><\/div>\n<\/div>\n<\/div>\n<p>\u8bfb\u53d6\u7aef\u53e3\uff0c\u7136\u540e\u542f\u52a8\u4e3b\u76d1\u7763\u8fdb\u7a0b\uff08\u6b64\u65f6\u8fd8\u4e0d\u4f1a\u76d1\u542c\u5904\u7406\u5ba2\u6237\u7aefsocket\u8bf7\u6c42\uff09\uff0c\u7d27\u63a5\u7740\u542f\u52a8\u5b50\u76d1\u7763\u8fdb\u7a0b\uff0c\u5f00\u59cb\u5904\u7406\u6765\u81ea\u5ba2\u6237\u7aef\u7684socket\u7684\u8fde\u63a5\u3002<\/p>\n<p>\u76d1\u7763\u8fdb\u7a0btcp_server_sup\u4e5f\u5f88\u7b80\u5355\uff1a<\/p>\n<div id=\"gist3945155\" class=\"gist\">\n<div class=\"gist-file\">\n<div class=\"gist-data gist-syntax\">\n<div class=\"file-data\">\n<table class=\"lines highlight\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"line-numbers\"><\/td>\n<td class=\"line-data\">\n<div id=\"file-tcp_server_sup-erl-LC1\" class=\"line\">&#8211;<span class=\"pl-k\">module<\/span>(<span class=\"pl-en\">tcp_server_sup<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC2\" class=\"line\">&#8211;<span class=\"pl-k\">author<\/span>(<span class=\"pl-c1\">&#8216;yongboy@gmail.com&#8217;<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC3\" class=\"line\">&#8211;<span class=\"pl-k\">behaviour<\/span>(<span class=\"pl-en\">supervisor<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC4\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">start_link<\/span>\/<span class=\"pl-c1\">1<\/span>, <span class=\"pl-en\">start_child<\/span>\/<span class=\"pl-c1\">0<\/span>]).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC5\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">init<\/span>\/<span class=\"pl-c1\">1<\/span>]).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC6\" class=\"line\">&#8211;<span class=\"pl-k\">define<\/span>(<span class=\"pl-en\">SERVER<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MODULE<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC7\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_sup-erl-LC8\" class=\"line\"><span class=\"pl-en\">start_link<\/span>(<span class=\"pl-vo\">LSock<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC9\" class=\"line\"><span class=\"pl-en\">supervisor<\/span>:<span class=\"pl-en\">start_link<\/span>({<span class=\"pl-c1\">local<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">SERVER<\/span>}, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MODULE<\/span>, [<span class=\"pl-vo\">LSock<\/span>]).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC10\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_sup-erl-LC11\" class=\"line\"><span class=\"pl-en\">start_child<\/span>() <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC12\" class=\"line\"><span class=\"pl-en\">supervisor<\/span>:<span class=\"pl-en\">start_child<\/span>(<span class=\"pl-k\">?<\/span><span class=\"pl-en\">SERVER<\/span>, []).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC13\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_sup-erl-LC14\" class=\"line\"><span class=\"pl-en\">init<\/span>([<span class=\"pl-vo\">LSock<\/span>]) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC15\" class=\"line\"><span class=\"pl-vo\">Server<\/span> <span class=\"pl-k\">=<\/span> {<span class=\"pl-c1\">tcp_server_handler<\/span>, {<span class=\"pl-c1\">tcp_server_handler<\/span>, <span class=\"pl-c1\">start_link<\/span>, [<span class=\"pl-vo\">LSock<\/span>]},<\/div>\n<div id=\"file-tcp_server_sup-erl-LC16\" class=\"line\"><span class=\"pl-c1\">temporary<\/span>, <span class=\"pl-c1\">brutal_kill<\/span>, <span class=\"pl-c1\">worker<\/span>, [<span class=\"pl-c1\">tcp_server_handler<\/span>]},<\/div>\n<div id=\"file-tcp_server_sup-erl-LC17\" class=\"line\"><span class=\"pl-vo\">Children<\/span> <span class=\"pl-k\">=<\/span> [<span class=\"pl-vo\">Server<\/span>],<\/div>\n<div id=\"file-tcp_server_sup-erl-LC18\" class=\"line\"><span class=\"pl-vo\">RestartStrategy<\/span> <span class=\"pl-k\">=<\/span> {<span class=\"pl-c1\">simple_one_for_one<\/span>, <span class=\"pl-c1\">0<\/span>, <span class=\"pl-c1\">1<\/span>},<\/div>\n<div id=\"file-tcp_server_sup-erl-LC19\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, {<span class=\"pl-vo\">RestartStrategy<\/span>, <span class=\"pl-vo\">Children<\/span>}}.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"gist-meta\"><a href=\"https:\/\/gist.github.com\/yongboy\/3945155\/raw\/tcp_server_sup.erl\">view raw<\/a><a href=\"https:\/\/gist.github.com\/yongboy\/3945155#file-tcp_server_sup-erl\">tcp_server_sup.erl<\/a> hosted with \u2764 by <a href=\"https:\/\/github.com\/\">GitHub<\/a><\/div>\n<\/div>\n<\/div>\n<p>\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u53ea\u6709\u8c03\u7528start_child\u51fd\u6570\u65f6\uff0c\u624d\u771f\u6b63\u8c03\u7528tcp_server_handler:start_link([LSock])\u51fd\u6570\u3002<\/p>\n<p>tcp_server_handler\u7684\u4ee3\u7801\u4e5f\u4e0d\u590d\u6742\uff1a<\/p>\n<div id=\"gist3945175\" class=\"gist\">\n<div class=\"gist-file\">\n<div class=\"gist-data gist-syntax\">\n<div class=\"file-data\">\n<table class=\"lines highlight\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"line-numbers\"><\/td>\n<td class=\"line-data\">\n<div id=\"file-tcp_server_handler-erl-LC1\" class=\"line\">&#8211;<span class=\"pl-k\">module<\/span>(<span class=\"pl-en\">tcp_server_handler<\/span>).<\/div>\n<div id=\"file-tcp_server_handler-erl-LC2\" class=\"line\">&#8211;<span class=\"pl-k\">behaviour<\/span>(<span class=\"pl-en\">gen_server<\/span>).<\/div>\n<div id=\"file-tcp_server_handler-erl-LC3\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">start_link<\/span>\/<span class=\"pl-c1\">1<\/span>]).<\/div>\n<div id=\"file-tcp_server_handler-erl-LC4\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">init<\/span>\/<span class=\"pl-c1\">1<\/span>, <span class=\"pl-en\">handle_call<\/span>\/<span class=\"pl-c1\">3<\/span>, <span class=\"pl-en\">handle_cast<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">handle_info<\/span>\/<span class=\"pl-c1\">2<\/span>,<\/div>\n<div id=\"file-tcp_server_handler-erl-LC5\" class=\"line\"><span class=\"pl-en\">terminate<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">code_change<\/span>\/<span class=\"pl-c1\">3<\/span>]).<\/div>\n<div id=\"file-tcp_server_handler-erl-LC6\" class=\"line\">&#8211;<span class=\"pl-k\">record<\/span>(<span class=\"pl-en\">state<\/span>, {<span class=\"pl-vo\">lsock<\/span>, <span class=\"pl-vo\">socket<\/span>, <span class=\"pl-vo\">addr<\/span>}).<\/div>\n<div id=\"file-tcp_server_handler-erl-LC7\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC8\" class=\"line\"><span class=\"pl-en\">start_link<\/span>(<span class=\"pl-vo\">LSock<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC9\" class=\"line\"><span class=\"pl-en\">gen_server<\/span>:<span class=\"pl-en\">start_link<\/span>(<span class=\"pl-k\">?<\/span><span class=\"pl-en\">MODULE<\/span>, [<span class=\"pl-vo\">LSock<\/span>], []).<\/div>\n<div id=\"file-tcp_server_handler-erl-LC10\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC11\" class=\"line\"><span class=\"pl-en\">init<\/span>([<span class=\"pl-vo\">Socket<\/span>]) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC12\" class=\"line\"><span class=\"pl-en\">inet<\/span>:<span class=\"pl-en\">setopts<\/span>(<span class=\"pl-vo\">Socket<\/span>, [{<span class=\"pl-c1\">active<\/span>, <span class=\"pl-c1\">once<\/span>}, {<span class=\"pl-c1\">packet<\/span>, <span class=\"pl-c1\">2<\/span>}, <span class=\"pl-c1\">binary<\/span>]),<\/div>\n<div id=\"file-tcp_server_handler-erl-LC13\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">lsock<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">Socket<\/span>}, <span class=\"pl-c1\">0<\/span>}.<\/div>\n<div id=\"file-tcp_server_handler-erl-LC14\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC15\" class=\"line\"><span class=\"pl-en\">handle_call<\/span>(<span class=\"pl-vo\">Msg<\/span>, <span class=\"pl-vo\">_From<\/span>, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC16\" class=\"line\">{<span class=\"pl-c1\">reply<\/span>, {<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">Msg<\/span>}, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<div id=\"file-tcp_server_handler-erl-LC17\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC18\" class=\"line\"><span class=\"pl-en\">handle_cast<\/span>(<span class=\"pl-c1\">stop<\/span>, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC19\" class=\"line\">{<span class=\"pl-c1\">stop<\/span>, <span class=\"pl-c1\">normal<\/span>, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<div id=\"file-tcp_server_handler-erl-LC20\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC21\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>({<span class=\"pl-c1\">tcp<\/span>, <span class=\"pl-vo\">Socket<\/span>, <span class=\"pl-vo\">Data<\/span>}, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC22\" class=\"line\"><span class=\"pl-en\">inet<\/span>:<span class=\"pl-en\">setopts<\/span>(<span class=\"pl-vo\">Socket<\/span>, [{<span class=\"pl-c1\">active<\/span>, <span class=\"pl-c1\">once<\/span>}]),<\/div>\n<div id=\"file-tcp_server_handler-erl-LC23\" class=\"line\"><span class=\"pl-en\">io<\/span>:<span class=\"pl-en\">format<\/span>(<span class=\"pl-s1\"><span class=\"pl-pds\">&#8220;<\/span><span class=\"pl-c1\">~p<\/span> got message <span class=\"pl-c1\">~p<\/span><span class=\"pl-cce\">\\n<\/span><span class=\"pl-pds\">&#8220;<\/span><\/span>, [<span class=\"pl-en\">self<\/span>(), <span class=\"pl-vo\">Data<\/span>]),<\/div>\n<div id=\"file-tcp_server_handler-erl-LC24\" class=\"line\"><span class=\"pl-c1\">ok<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">send<\/span>(<span class=\"pl-vo\">Socket<\/span>, &lt;&lt;<span class=\"pl-s1\"><span class=\"pl-pds\">&#8220;<\/span>Echo back : <span class=\"pl-pds\">&#8220;<\/span><\/span>, <span class=\"pl-vo\">Data<\/span>\/<span class=\"pl-st\">binary<\/span>&gt;&gt;),<\/div>\n<div id=\"file-tcp_server_handler-erl-LC25\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-vo\">State<\/span>};<\/div>\n<div id=\"file-tcp_server_handler-erl-LC26\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC27\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>({<span class=\"pl-c1\">tcp_closed<\/span>, <span class=\"pl-vo\">Socket<\/span>}, <span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">addr<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">Addr<\/span>} <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">StateData<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC28\" class=\"line\"><span class=\"pl-en\">error_logger<\/span>:<span class=\"pl-en\">info_msg<\/span>(<span class=\"pl-s1\"><span class=\"pl-pds\">&#8220;<\/span><span class=\"pl-c1\">~p<\/span> Client <span class=\"pl-c1\">~p<\/span> disconnected.<span class=\"pl-cce\">\\n<\/span><span class=\"pl-pds\">&#8220;<\/span><\/span>, [<span class=\"pl-en\">self<\/span>(), <span class=\"pl-vo\">Addr<\/span>]),<\/div>\n<div id=\"file-tcp_server_handler-erl-LC29\" class=\"line\">{<span class=\"pl-c1\">stop<\/span>, <span class=\"pl-c1\">normal<\/span>, <span class=\"pl-vo\">StateData<\/span>};<\/div>\n<div id=\"file-tcp_server_handler-erl-LC30\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC31\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>(<span class=\"pl-c1\">timeout<\/span>, <span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">lsock<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">LSock<\/span>} <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC32\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">ClientSocket<\/span>} <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">accept<\/span>(<span class=\"pl-vo\">LSock<\/span>),<\/div>\n<div id=\"file-tcp_server_handler-erl-LC33\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, {<span class=\"pl-vo\">IP<\/span>, <span class=\"pl-vo\">_Port<\/span>}} <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">inet<\/span>:<span class=\"pl-en\">peername<\/span>(<span class=\"pl-vo\">ClientSocket<\/span>),<\/div>\n<div id=\"file-tcp_server_handler-erl-LC34\" class=\"line\"><span class=\"pl-en\">tcp_server_sup<\/span>:<span class=\"pl-en\">start_child<\/span>(),<\/div>\n<div id=\"file-tcp_server_handler-erl-LC35\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-vo\">State<\/span><span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">socket<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">ClientSocket<\/span>, <span class=\"pl-vo\">addr<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">IP<\/span>}};<\/div>\n<div id=\"file-tcp_server_handler-erl-LC36\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC37\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>(<span class=\"pl-vo\">_Info<\/span>, <span class=\"pl-vo\">StateData<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC38\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-vo\">StateData<\/span>}.<\/div>\n<div id=\"file-tcp_server_handler-erl-LC39\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC40\" class=\"line\"><span class=\"pl-en\">terminate<\/span>(<span class=\"pl-vo\">_Reason<\/span>, <span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">socket<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">Socket<\/span>}) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC41\" class=\"line\">(<span class=\"pl-k\">catch<\/span> <span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">close<\/span>(<span class=\"pl-vo\">Socket<\/span>)),<\/div>\n<div id=\"file-tcp_server_handler-erl-LC42\" class=\"line\"><span class=\"pl-c1\">ok<\/span>.<\/div>\n<div id=\"file-tcp_server_handler-erl-LC43\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_handler-erl-LC44\" class=\"line\"><span class=\"pl-en\">code_change<\/span>(<span class=\"pl-vo\">_OldVsn<\/span>, <span class=\"pl-vo\">State<\/span>, <span class=\"pl-vo\">_Extra<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_handler-erl-LC45\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"gist-meta\"><a href=\"https:\/\/gist.github.com\/yongboy\/3945175\/raw\/tcp_server_handler.erl\">view raw<\/a><a href=\"https:\/\/gist.github.com\/yongboy\/3945175#file-tcp_server_handler-erl\">tcp_server_handler.erl<\/a> hosted with \u2764 by <a href=\"https:\/\/github.com\/\">GitHub<\/a><\/div>\n<\/div>\n<\/div>\n<p>\u4ee3\u7801\u5f88\u7cbe\u5de7\uff0c\u6709\u4e9b\u5c0f\u6280\u5de7\u5728\u91cc\u9762\u3002\u5b50\u76d1\u7763\u8fdb\u7a0b\u8c03\u7528start_link\u51fd\u6570\uff0cinit\u4f1a\u8fd4\u56de{ok, #state{lsock = Socket}, 0}. \u6570\u5b570\u4ee3\u8868\u4e86timeout\u6570\u503c\uff0c\u610f\u5473\u7740gen_server\u9a6c\u4e0a\u8c03\u7528handle_info(timeout, #state{lsock = LSock} = State)\u51fd\u6570\uff0c\u6267\u884c\u5ba2\u6237\u7aefsocket\u76d1\u542c\uff0c\u963b\u585e\u4e8e\u6b64\uff0c\u4f46\u4e0d\u4f1a\u5f71\u54cd\u5728\u6b64\u6a21\u5f0f\u4e0b\u5176\u5b83\u51fd\u6570\u7684\u8c03\u7528\u3002\u76f4\u5230\u6709\u5ba2\u6237\u7aef\u8fdb\u6765\uff0c\u7136\u540e\u542f\u52a8\u4e00\u4e2a\u65b0\u7684\u5b50\u76d1\u7763\u8fdb\u7a0btcp_server_handler\uff0c\u5f53\u524d\u5b50\u76d1\u7763\u8fdb\u7a0b\u89e3\u9664\u963b\u585e\u3002<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>\u57fa\u4e8eprim_inet\u5b9e\u73b0<\/strong><\/h3>\n<p>\u8fd9\u4e2a\u5b9e\u73b0\u5e08\u4ece\u4e8eNon-blocking TCP server using OTP principles\u4e00\u6587\uff0c\u4f46\u5b50\u8fdb\u7a0b\u6539\u4e3a\u4e86gen_server\u5b9e\u73b0\u3002<\/p>\n<p>\u770b\u4e00\u770b\u5165\u53e3\uff0c\u5f88\u7b80\u5355\u7684\uff1a<\/p>\n<div id=\"gist3945273\" class=\"gist\">\n<div class=\"gist-file\">\n<div class=\"gist-data gist-syntax\">\n<div class=\"file-data\">\n<table class=\"lines highlight\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"line-numbers\"><\/td>\n<td class=\"line-data\">\n<div id=\"file-tcp_server_app-erl-LC1\" class=\"line\">&#8211;<span class=\"pl-k\">module<\/span>(<span class=\"pl-en\">tcp_server_app<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC2\" class=\"line\">&#8211;<span class=\"pl-k\">author<\/span>(<span class=\"pl-c1\">&#8216;yongboy@gmail.com&#8217;<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC3\" class=\"line\">&#8211;<span class=\"pl-k\">behaviour<\/span>(<span class=\"pl-en\">application<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC4\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">start_client<\/span>\/<span class=\"pl-c1\">1<\/span>]).<\/div>\n<div id=\"file-tcp_server_app-erl-LC5\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">start<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">stop<\/span>\/<span class=\"pl-c1\">1<\/span>]).<\/div>\n<div id=\"file-tcp_server_app-erl-LC6\" class=\"line\">&#8211;<span class=\"pl-k\">define<\/span>(<span class=\"pl-en\">DEF_PORT<\/span>, <span class=\"pl-c1\">2222<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC7\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_app-erl-LC8\" class=\"line\"><span class=\"pl-c\">%% A startup function for spawning new client connection handling FSM.<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC9\" class=\"line\"><span class=\"pl-c\">%% To be called by the TCP listener process.<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC10\" class=\"line\"><span class=\"pl-en\">start_client<\/span>(<span class=\"pl-vo\">Socket<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC11\" class=\"line\"><span class=\"pl-en\">tcp_server_sup<\/span>:<span class=\"pl-en\">start_child<\/span>(<span class=\"pl-vo\">Socket<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC12\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_app-erl-LC13\" class=\"line\"><span class=\"pl-en\">start<\/span>(<span class=\"pl-vo\">_Type<\/span>, <span class=\"pl-vo\">_Args<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC14\" class=\"line\"><span class=\"pl-vo\">ListenPort<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">get_app_env<\/span>(<span class=\"pl-c1\">listen_port<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">DEF_PORT<\/span>),<\/div>\n<div id=\"file-tcp_server_app-erl-LC15\" class=\"line\"><span class=\"pl-en\">tcp_server_sup<\/span>:<span class=\"pl-en\">start_link<\/span>(<span class=\"pl-vo\">ListenPort<\/span>, <span class=\"pl-c1\">tcp_client_handler<\/span>).<\/div>\n<div id=\"file-tcp_server_app-erl-LC16\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_app-erl-LC17\" class=\"line\"><span class=\"pl-en\">stop<\/span>(<span class=\"pl-vo\">_S<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC18\" class=\"line\"><span class=\"pl-c1\">ok<\/span>.<\/div>\n<div id=\"file-tcp_server_app-erl-LC19\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_app-erl-LC20\" class=\"line\"><span class=\"pl-en\">get_app_env<\/span>(<span class=\"pl-vo\">Opt<\/span>, <span class=\"pl-vo\">Default<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC21\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">application<\/span>:<span class=\"pl-en\">get_env<\/span>(<span class=\"pl-en\">application<\/span>:<span class=\"pl-en\">get_application<\/span>(), <span class=\"pl-vo\">Opt<\/span>) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC22\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">Val<\/span>} -&gt; <span class=\"pl-vo\">Val<\/span>;<\/div>\n<div id=\"file-tcp_server_app-erl-LC23\" class=\"line\"><span class=\"pl-v\">_<\/span> -&gt;<\/div>\n<div id=\"file-tcp_server_app-erl-LC24\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">init<\/span>:<span class=\"pl-en\">get_argument<\/span>(<span class=\"pl-vo\">Opt<\/span>) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC25\" class=\"line\">[[<span class=\"pl-vo\">Val<\/span> | <span class=\"pl-v\">_<\/span>]] -&gt; <span class=\"pl-vo\">Val<\/span>;<\/div>\n<div id=\"file-tcp_server_app-erl-LC26\" class=\"line\"><span class=\"pl-c1\">error<\/span> -&gt; <span class=\"pl-vo\">Default<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC27\" class=\"line\"><span class=\"pl-k\">end<\/span><\/div>\n<div id=\"file-tcp_server_app-erl-LC28\" class=\"line\"><span class=\"pl-k\">end<\/span>.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"gist-meta\"><a href=\"https:\/\/gist.github.com\/yongboy\/3945273\/raw\/tcp_server_app.erl\">view raw<\/a><a href=\"https:\/\/gist.github.com\/yongboy\/3945273#file-tcp_server_app-erl\">tcp_server_app.erl<\/a> hosted with \u2764 by <a href=\"https:\/\/github.com\/\">GitHub<\/a><\/div>\n<\/div>\n<\/div>\n<p>\u76d1\u7763\u8fdb\u7a0b\u4ee3\u7801\uff1a<\/p>\n<div id=\"gist3945280\" class=\"gist\">\n<div class=\"gist-file\">\n<div class=\"gist-data gist-syntax\">\n<div class=\"file-data\">\n<table class=\"lines highlight\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"line-numbers\"><\/td>\n<td class=\"line-data\">\n<div id=\"file-tcp_server_sup-erl-LC1\" class=\"line\">&#8211;<span class=\"pl-k\">module<\/span>(<span class=\"pl-en\">tcp_server_sup<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC2\" class=\"line\">&#8211;<span class=\"pl-k\">author<\/span>(<span class=\"pl-c1\">&#8216;yongboy@gmail.com&#8217;<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC3\" class=\"line\">&#8211;<span class=\"pl-k\">behaviour<\/span>(<span class=\"pl-en\">supervisor<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC4\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">start_child<\/span>\/<span class=\"pl-c1\">1<\/span>, <span class=\"pl-en\">start_link<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">init<\/span>\/<span class=\"pl-c1\">1<\/span>]).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC5\" class=\"line\">&#8211;<span class=\"pl-k\">define<\/span>(<span class=\"pl-en\">SERVER<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MODULE<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC6\" class=\"line\">&#8211;<span class=\"pl-k\">define<\/span>(<span class=\"pl-en\">CLIENT_SUP<\/span>, <span class=\"pl-c1\">tcp_client_sup<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC7\" class=\"line\">&#8211;<span class=\"pl-k\">define<\/span>(<span class=\"pl-en\">MAX_RESTART<\/span>, <span class=\"pl-c1\">5<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC8\" class=\"line\">&#8211;<span class=\"pl-k\">define<\/span>(<span class=\"pl-en\">MAX_TIME<\/span>, <span class=\"pl-c1\">60<\/span>).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC9\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_sup-erl-LC10\" class=\"line\"><span class=\"pl-en\">start_child<\/span>(<span class=\"pl-vo\">Socket<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC11\" class=\"line\"><span class=\"pl-en\">supervisor<\/span>:<span class=\"pl-en\">start_child<\/span>(<span class=\"pl-k\">?<\/span><span class=\"pl-en\">CLIENT_SUP<\/span>, [<span class=\"pl-vo\">Socket<\/span>]).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC12\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_sup-erl-LC13\" class=\"line\"><span class=\"pl-en\">start_link<\/span>(<span class=\"pl-vo\">ListenPort<\/span>, <span class=\"pl-vo\">HandleMoudle<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC14\" class=\"line\"><span class=\"pl-en\">supervisor<\/span>:<span class=\"pl-en\">start_link<\/span>({<span class=\"pl-c1\">local<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">SERVER<\/span>}, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MODULE<\/span>, [<span class=\"pl-vo\">ListenPort<\/span>, <span class=\"pl-vo\">HandleMoudle<\/span>]).<\/div>\n<div id=\"file-tcp_server_sup-erl-LC15\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_sup-erl-LC16\" class=\"line\"><span class=\"pl-en\">init<\/span>([<span class=\"pl-vo\">Port<\/span>, <span class=\"pl-vo\">Module<\/span>]) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC17\" class=\"line\"><span class=\"pl-vo\">TcpListener<\/span> <span class=\"pl-k\">=<\/span> {<span class=\"pl-c1\">tcp_server_sup<\/span>, <span class=\"pl-c\">% Id = internal id<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC18\" class=\"line\">{<span class=\"pl-c1\">tcp_listener<\/span>, <span class=\"pl-c1\">start_link<\/span>, [<span class=\"pl-vo\">Port<\/span>, <span class=\"pl-vo\">Module<\/span>]}, <span class=\"pl-c\">% StartFun = {M, F, A}<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC19\" class=\"line\"><span class=\"pl-c1\">permanent<\/span>, <span class=\"pl-c\">% Restart = permanent | transient | temporary<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC20\" class=\"line\"><span class=\"pl-c1\">2000<\/span>, <span class=\"pl-c\">% Shutdown = brutal_kill | int() &gt;= 0 | infinity<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC21\" class=\"line\"><span class=\"pl-c1\">worker<\/span>, <span class=\"pl-c\">% Type = worker | supervisor<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC22\" class=\"line\">[<span class=\"pl-c1\">tcp_listener<\/span>] <span class=\"pl-c\">% Modules = [Module] | dynamic<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC23\" class=\"line\">},<\/div>\n<div id=\"file-tcp_server_sup-erl-LC24\" class=\"line\"><span class=\"pl-vo\">TcpClientSupervisor<\/span> <span class=\"pl-k\">=<\/span> {<span class=\"pl-k\">?<\/span><span class=\"pl-en\">CLIENT_SUP<\/span>,<\/div>\n<div id=\"file-tcp_server_sup-erl-LC25\" class=\"line\">{<span class=\"pl-c1\">supervisor<\/span>, <span class=\"pl-c1\">start_link<\/span>, [{<span class=\"pl-c1\">local<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">CLIENT_SUP<\/span>}, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MODULE<\/span>, [<span class=\"pl-vo\">Module<\/span>]]},<\/div>\n<div id=\"file-tcp_server_sup-erl-LC26\" class=\"line\"><span class=\"pl-c1\">permanent<\/span>,<\/div>\n<div id=\"file-tcp_server_sup-erl-LC27\" class=\"line\"><span class=\"pl-c1\">infinity<\/span>,<\/div>\n<div id=\"file-tcp_server_sup-erl-LC28\" class=\"line\"><span class=\"pl-c1\">supervisor<\/span>,<\/div>\n<div id=\"file-tcp_server_sup-erl-LC29\" class=\"line\">[]<\/div>\n<div id=\"file-tcp_server_sup-erl-LC30\" class=\"line\">},<\/div>\n<div id=\"file-tcp_server_sup-erl-LC31\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>,<\/div>\n<div id=\"file-tcp_server_sup-erl-LC32\" class=\"line\">{{<span class=\"pl-c1\">one_for_one<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MAX_RESTART<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MAX_TIME<\/span>},<\/div>\n<div id=\"file-tcp_server_sup-erl-LC33\" class=\"line\">[<span class=\"pl-vo\">TcpListener<\/span>, <span class=\"pl-vo\">TcpClientSupervisor<\/span>]<\/div>\n<div id=\"file-tcp_server_sup-erl-LC34\" class=\"line\">}<\/div>\n<div id=\"file-tcp_server_sup-erl-LC35\" class=\"line\">};<\/div>\n<div id=\"file-tcp_server_sup-erl-LC36\" class=\"line\"><\/div>\n<div id=\"file-tcp_server_sup-erl-LC37\" class=\"line\"><span class=\"pl-en\">init<\/span>([<span class=\"pl-vo\">Module<\/span>]) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC38\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>,<\/div>\n<div id=\"file-tcp_server_sup-erl-LC39\" class=\"line\">{<span class=\"pl-vo\">_SupFlags<\/span> <span class=\"pl-k\">=<\/span> {<span class=\"pl-c1\">simple_one_for_one<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MAX_RESTART<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MAX_TIME<\/span>},<\/div>\n<div id=\"file-tcp_server_sup-erl-LC40\" class=\"line\">[<\/div>\n<div id=\"file-tcp_server_sup-erl-LC41\" class=\"line\"><span class=\"pl-c\">% TCP Client<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC42\" class=\"line\">{ <span class=\"pl-c1\">undefined<\/span>, <span class=\"pl-c\">% Id = internal id<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC43\" class=\"line\">{<span class=\"pl-vo\">Module<\/span>, <span class=\"pl-c1\">start_link<\/span>, []}, <span class=\"pl-c\">% StartFun = {M, F, A}<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC44\" class=\"line\"><span class=\"pl-c1\">temporary<\/span>, <span class=\"pl-c\">% Restart = permanent | transient | temporary<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC45\" class=\"line\"><span class=\"pl-c1\">2000<\/span>, <span class=\"pl-c\">% Shutdown = brutal_kill | int() &gt;= 0 | infinity<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC46\" class=\"line\"><span class=\"pl-c1\">worker<\/span>, <span class=\"pl-c\">% Type = worker | supervisor<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC47\" class=\"line\">[] <span class=\"pl-c\">% Modules = [Module] | dynamic<\/span><\/div>\n<div id=\"file-tcp_server_sup-erl-LC48\" class=\"line\">}<\/div>\n<div id=\"file-tcp_server_sup-erl-LC49\" class=\"line\">]<\/div>\n<div id=\"file-tcp_server_sup-erl-LC50\" class=\"line\">}<\/div>\n<div id=\"file-tcp_server_sup-erl-LC51\" class=\"line\">}.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"gist-meta\"><a href=\"https:\/\/gist.github.com\/yongboy\/3945280\/raw\/tcp_server_sup.erl\">view raw<\/a><a href=\"https:\/\/gist.github.com\/yongboy\/3945280#file-tcp_server_sup-erl\">tcp_server_sup.erl<\/a> hosted with \u2764 by <a href=\"https:\/\/github.com\/\">GitHub<\/a><\/div>\n<\/div>\n<\/div>\n<p>\u7b56\u7565\u4e0d\u4e00\u6837\uff0cone_for_one\u5305\u62ec\u4e86\u4e00\u4e2a\u76d1\u542c\u8fdb\u7a0btcp_listener\uff0c\u8fd8\u5305\u542b\u4e86\u4e00\u4e2atcp_client_sup\u8fdb\u7a0b\u6811(simple_one_for_one\u7b56\u7565)<\/p>\n<p>tcp_listener\u5355\u72ec\u4e00\u4e2a\u8fdb\u7a0b\u7528\u4e8e\u76d1\u542c\u6765\u81ea\u5ba2\u6237\u7aefsocket\u7684\u8fde\u63a5:<\/p>\n<div id=\"gist3945295\" class=\"gist\">\n<div class=\"gist-file\">\n<div class=\"gist-data gist-syntax\">\n<div class=\"file-data\">\n<table class=\"lines highlight\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"line-numbers\"><\/td>\n<td class=\"line-data\">\n<div id=\"file-tcp_listener-erl-LC1\" class=\"line\">&#8211;<span class=\"pl-k\">module<\/span>(<span class=\"pl-en\">tcp_listener<\/span>).<\/div>\n<div id=\"file-tcp_listener-erl-LC2\" class=\"line\">&#8211;<span class=\"pl-k\">author<\/span>(<span class=\"pl-c1\">&#8216;saleyn@gmail.com&#8217;<\/span>).<\/div>\n<div id=\"file-tcp_listener-erl-LC3\" class=\"line\">&#8211;<span class=\"pl-k\">behaviour<\/span>(<span class=\"pl-en\">gen_server<\/span>).<\/div>\n<div id=\"file-tcp_listener-erl-LC4\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">start_link<\/span>\/<span class=\"pl-c1\">2<\/span>]).<\/div>\n<div id=\"file-tcp_listener-erl-LC5\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">init<\/span>\/<span class=\"pl-c1\">1<\/span>, <span class=\"pl-en\">handle_call<\/span>\/<span class=\"pl-c1\">3<\/span>, <span class=\"pl-en\">handle_cast<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">handle_info<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">terminate<\/span>\/<span class=\"pl-c1\">2<\/span>,<\/div>\n<div id=\"file-tcp_listener-erl-LC6\" class=\"line\"><span class=\"pl-en\">code_change<\/span>\/<span class=\"pl-c1\">3<\/span>]).<\/div>\n<div id=\"file-tcp_listener-erl-LC7\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC8\" class=\"line\">&#8211;<span class=\"pl-k\">record<\/span>(<span class=\"pl-en\">state<\/span>, {<\/div>\n<div id=\"file-tcp_listener-erl-LC9\" class=\"line\"><span class=\"pl-vo\">listener<\/span>, <span class=\"pl-c\">% Listening socket<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC10\" class=\"line\"><span class=\"pl-vo\">acceptor<\/span>, <span class=\"pl-c\">% Asynchronous acceptor&#8217;s internal reference<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC11\" class=\"line\"><span class=\"pl-vo\">module<\/span> <span class=\"pl-c\">% FSM handling module<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC12\" class=\"line\">}).<\/div>\n<div id=\"file-tcp_listener-erl-LC13\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC14\" class=\"line\"><span class=\"pl-en\">start_link<\/span>(<span class=\"pl-vo\">Port<\/span>, <span class=\"pl-vo\">Module<\/span>) <span class=\"pl-k\">when<\/span> <span class=\"pl-en\">is_integer<\/span>(<span class=\"pl-vo\">Port<\/span>), <span class=\"pl-en\">is_atom<\/span>(<span class=\"pl-vo\">Module<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC15\" class=\"line\"><span class=\"pl-en\">gen_server<\/span>:<span class=\"pl-en\">start_link<\/span>({<span class=\"pl-c1\">local<\/span>, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MODULE<\/span>}, <span class=\"pl-k\">?<\/span><span class=\"pl-en\">MODULE<\/span>, [<span class=\"pl-vo\">Port<\/span>, <span class=\"pl-vo\">Module<\/span>], []).<\/div>\n<div id=\"file-tcp_listener-erl-LC16\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC17\" class=\"line\"><span class=\"pl-en\">init<\/span>([<span class=\"pl-vo\">Port<\/span>, <span class=\"pl-vo\">Module<\/span>]) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC18\" class=\"line\"><span class=\"pl-en\">process_flag<\/span>(<span class=\"pl-c1\">trap_exit<\/span>, <span class=\"pl-c1\">true<\/span>),<\/div>\n<div id=\"file-tcp_listener-erl-LC19\" class=\"line\"><span class=\"pl-vo\">Opts<\/span> <span class=\"pl-k\">=<\/span> [<span class=\"pl-c1\">binary<\/span>, {<span class=\"pl-c1\">packet<\/span>, <span class=\"pl-c1\">2<\/span>}, {<span class=\"pl-c1\">reuseaddr<\/span>, <span class=\"pl-c1\">true<\/span>},<\/div>\n<div id=\"file-tcp_listener-erl-LC20\" class=\"line\">{<span class=\"pl-c1\">keepalive<\/span>, <span class=\"pl-c1\">true<\/span>}, {<span class=\"pl-c1\">backlog<\/span>, <span class=\"pl-c1\">30<\/span>}, {<span class=\"pl-c1\">active<\/span>, <span class=\"pl-c1\">false<\/span>}],<\/div>\n<div id=\"file-tcp_listener-erl-LC21\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">listen<\/span>(<span class=\"pl-vo\">Port<\/span>, <span class=\"pl-vo\">Opts<\/span>) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC22\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">Listen_socket<\/span>} -&gt;<\/div>\n<div id=\"file-tcp_listener-erl-LC23\" class=\"line\"><span class=\"pl-c\">%%Create first accepting process<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC24\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">Ref<\/span>} <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">prim_inet<\/span>:<span class=\"pl-en\">async_accept<\/span>(<span class=\"pl-vo\">Listen_socket<\/span>, <span class=\"pl-k\">&#8211;<\/span><span class=\"pl-c1\">1<\/span>),<\/div>\n<div id=\"file-tcp_listener-erl-LC25\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">listener<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">Listen_socket<\/span>,<\/div>\n<div id=\"file-tcp_listener-erl-LC26\" class=\"line\"><span class=\"pl-vo\">acceptor<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">Ref<\/span>,<\/div>\n<div id=\"file-tcp_listener-erl-LC27\" class=\"line\"><span class=\"pl-vo\">module<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">Module<\/span>}};<\/div>\n<div id=\"file-tcp_listener-erl-LC28\" class=\"line\">{<span class=\"pl-c1\">error<\/span>, <span class=\"pl-vo\">Reason<\/span>} -&gt;<\/div>\n<div id=\"file-tcp_listener-erl-LC29\" class=\"line\">{<span class=\"pl-c1\">stop<\/span>, <span class=\"pl-vo\">Reason<\/span>}<\/div>\n<div id=\"file-tcp_listener-erl-LC30\" class=\"line\"><span class=\"pl-k\">end<\/span>.<\/div>\n<div id=\"file-tcp_listener-erl-LC31\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC32\" class=\"line\"><span class=\"pl-en\">handle_call<\/span>(<span class=\"pl-vo\">Request<\/span>, <span class=\"pl-vo\">_From<\/span>, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC33\" class=\"line\">{<span class=\"pl-c1\">stop<\/span>, {<span class=\"pl-c1\">unknown_call<\/span>, <span class=\"pl-vo\">Request<\/span>}, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<div id=\"file-tcp_listener-erl-LC34\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC35\" class=\"line\"><span class=\"pl-en\">handle_cast<\/span>(<span class=\"pl-vo\">_Msg<\/span>, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC36\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<div id=\"file-tcp_listener-erl-LC37\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC38\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>({<span class=\"pl-c1\">inet_async<\/span>, <span class=\"pl-vo\">ListSock<\/span>, <span class=\"pl-vo\">Ref<\/span>, {<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">CliSocket<\/span>}},<\/div>\n<div id=\"file-tcp_listener-erl-LC39\" class=\"line\"><span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">listener<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">ListSock<\/span>, <span class=\"pl-vo\">acceptor<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">Ref<\/span>, <span class=\"pl-vo\">module<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">Module<\/span>} <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC40\" class=\"line\"><span class=\"pl-k\">try<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC41\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">set_sockopt<\/span>(<span class=\"pl-vo\">ListSock<\/span>, <span class=\"pl-vo\">CliSocket<\/span>) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC42\" class=\"line\"><span class=\"pl-c1\">ok<\/span> -&gt; <span class=\"pl-c1\">ok<\/span>;<\/div>\n<div id=\"file-tcp_listener-erl-LC43\" class=\"line\">{<span class=\"pl-c1\">error<\/span>, <span class=\"pl-vo\">Reason<\/span>} -&gt; <span class=\"pl-en\">exit<\/span>({<span class=\"pl-c1\">set_sockopt<\/span>, <span class=\"pl-vo\">Reason<\/span>})<\/div>\n<div id=\"file-tcp_listener-erl-LC44\" class=\"line\"><span class=\"pl-k\">end<\/span>,<\/div>\n<div id=\"file-tcp_listener-erl-LC45\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC46\" class=\"line\"><span class=\"pl-c\">%% New client connected &#8211; spawn a new process using the simple_one_for_one<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC47\" class=\"line\"><span class=\"pl-c\">%% supervisor.<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC48\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">Pid<\/span>} <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">tcp_server_app<\/span>:<span class=\"pl-en\">start_client<\/span>(<span class=\"pl-vo\">CliSocket<\/span>),<\/div>\n<div id=\"file-tcp_listener-erl-LC49\" class=\"line\"><span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">controlling_process<\/span>(<span class=\"pl-vo\">CliSocket<\/span>, <span class=\"pl-vo\">Pid<\/span>),<\/div>\n<div id=\"file-tcp_listener-erl-LC50\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC51\" class=\"line\"><span class=\"pl-c\">%% Signal the network driver that we are ready to accept another connection<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC52\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">prim_inet<\/span>:<span class=\"pl-en\">async_accept<\/span>(<span class=\"pl-vo\">ListSock<\/span>, <span class=\"pl-k\">&#8211;<\/span><span class=\"pl-c1\">1<\/span>) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC53\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">NewRef<\/span>} -&gt; <span class=\"pl-c1\">ok<\/span>;<\/div>\n<div id=\"file-tcp_listener-erl-LC54\" class=\"line\">{<span class=\"pl-c1\">error<\/span>, <span class=\"pl-vo\">NewRef<\/span>} -&gt; <span class=\"pl-en\">exit<\/span>({<span class=\"pl-c1\">async_accept<\/span>, <span class=\"pl-en\">inet<\/span>:<span class=\"pl-en\">format_error<\/span>(<span class=\"pl-vo\">NewRef<\/span>)})<\/div>\n<div id=\"file-tcp_listener-erl-LC55\" class=\"line\"><span class=\"pl-k\">end<\/span>,<\/div>\n<div id=\"file-tcp_listener-erl-LC56\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC57\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-vo\">State<\/span><span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">acceptor<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">NewRef<\/span>}}<\/div>\n<div id=\"file-tcp_listener-erl-LC58\" class=\"line\"><span class=\"pl-k\">catch<\/span> <span class=\"pl-c1\">exit<\/span>:<span class=\"pl-vo\">Why<\/span> -&gt;<\/div>\n<div id=\"file-tcp_listener-erl-LC59\" class=\"line\"><span class=\"pl-en\">error_logger<\/span>:<span class=\"pl-en\">error_msg<\/span>(<span class=\"pl-s1\"><span class=\"pl-pds\">&#8220;<\/span>Error in async accept: <span class=\"pl-c1\">~p<\/span>.<span class=\"pl-cce\">\\n<\/span><span class=\"pl-pds\">&#8220;<\/span><\/span>, [<span class=\"pl-vo\">Why<\/span>]),<\/div>\n<div id=\"file-tcp_listener-erl-LC60\" class=\"line\">{<span class=\"pl-c1\">stop<\/span>, <span class=\"pl-vo\">Why<\/span>, <span class=\"pl-vo\">State<\/span>}<\/div>\n<div id=\"file-tcp_listener-erl-LC61\" class=\"line\"><span class=\"pl-k\">end<\/span>;<\/div>\n<div id=\"file-tcp_listener-erl-LC62\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC63\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>({<span class=\"pl-c1\">inet_async<\/span>, <span class=\"pl-vo\">ListSock<\/span>, <span class=\"pl-vo\">Ref<\/span>, <span class=\"pl-vo\">Error<\/span>}, <span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">listener<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">ListSock<\/span>, <span class=\"pl-vo\">acceptor<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">Ref<\/span>} <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC64\" class=\"line\"><span class=\"pl-en\">error_logger<\/span>:<span class=\"pl-en\">error_msg<\/span>(<span class=\"pl-s1\"><span class=\"pl-pds\">&#8220;<\/span>Error in socket acceptor: <span class=\"pl-c1\">~p<\/span>.<span class=\"pl-cce\">\\n<\/span><span class=\"pl-pds\">&#8220;<\/span><\/span>, [<span class=\"pl-vo\">Error<\/span>]),<\/div>\n<div id=\"file-tcp_listener-erl-LC65\" class=\"line\">{<span class=\"pl-c1\">stop<\/span>, <span class=\"pl-vo\">Error<\/span>, <span class=\"pl-vo\">State<\/span>};<\/div>\n<div id=\"file-tcp_listener-erl-LC66\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC67\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>(<span class=\"pl-vo\">_Info<\/span>, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC68\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<div id=\"file-tcp_listener-erl-LC69\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC70\" class=\"line\"><span class=\"pl-en\">terminate<\/span>(<span class=\"pl-vo\">_Reason<\/span>, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC71\" class=\"line\"><span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">close<\/span>(<span class=\"pl-vo\">State<\/span><span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>.<span class=\"pl-vo\">listener<\/span>),<\/div>\n<div id=\"file-tcp_listener-erl-LC72\" class=\"line\"><span class=\"pl-c1\">ok<\/span>.<\/div>\n<div id=\"file-tcp_listener-erl-LC73\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC74\" class=\"line\"><span class=\"pl-en\">code_change<\/span>(<span class=\"pl-vo\">_OldVsn<\/span>, <span class=\"pl-vo\">State<\/span>, <span class=\"pl-vo\">_Extra<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC75\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<div id=\"file-tcp_listener-erl-LC76\" class=\"line\"><\/div>\n<div id=\"file-tcp_listener-erl-LC77\" class=\"line\"><span class=\"pl-c\">%% Taken from prim_inet. We are merely copying some socket options from the<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC78\" class=\"line\"><span class=\"pl-c\">%% listening socket to the new client socket.<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC79\" class=\"line\"><span class=\"pl-en\">set_sockopt<\/span>(<span class=\"pl-vo\">ListSock<\/span>, <span class=\"pl-vo\">CliSocket<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC80\" class=\"line\"><span class=\"pl-c1\">true<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">inet_db<\/span>:<span class=\"pl-en\">register_socket<\/span>(<span class=\"pl-vo\">CliSocket<\/span>, <span class=\"pl-c1\">inet_tcp<\/span>),<\/div>\n<div id=\"file-tcp_listener-erl-LC81\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">prim_inet<\/span>:<span class=\"pl-en\">getopts<\/span>(<span class=\"pl-vo\">ListSock<\/span>, [<span class=\"pl-c1\">active<\/span>, <span class=\"pl-c1\">nodelay<\/span>, <span class=\"pl-c1\">keepalive<\/span>, <span class=\"pl-c1\">delay_send<\/span>, <span class=\"pl-c1\">priority<\/span>, <span class=\"pl-c1\">tos<\/span>]) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC82\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">Opts<\/span>} -&gt;<\/div>\n<div id=\"file-tcp_listener-erl-LC83\" class=\"line\"><span class=\"pl-k\">case<\/span> <span class=\"pl-en\">prim_inet<\/span>:<span class=\"pl-en\">setopts<\/span>(<span class=\"pl-vo\">CliSocket<\/span>, <span class=\"pl-vo\">Opts<\/span>) <span class=\"pl-k\">of<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC84\" class=\"line\"><span class=\"pl-c1\">ok<\/span> -&gt; <span class=\"pl-c1\">ok<\/span>;<\/div>\n<div id=\"file-tcp_listener-erl-LC85\" class=\"line\"><span class=\"pl-vo\">Error<\/span> -&gt; <span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">close<\/span>(<span class=\"pl-vo\">CliSocket<\/span>), <span class=\"pl-vo\">Error<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC86\" class=\"line\"><span class=\"pl-k\">end<\/span>;<\/div>\n<div id=\"file-tcp_listener-erl-LC87\" class=\"line\"><span class=\"pl-vo\">Error<\/span> -&gt;<\/div>\n<div id=\"file-tcp_listener-erl-LC88\" class=\"line\"><span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">close<\/span>(<span class=\"pl-vo\">CliSocket<\/span>), <span class=\"pl-vo\">Error<\/span><\/div>\n<div id=\"file-tcp_listener-erl-LC89\" class=\"line\"><span class=\"pl-k\">end<\/span>.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"gist-meta\"><a href=\"https:\/\/gist.github.com\/yongboy\/3945295\/raw\/tcp_listener.erl\">view raw<\/a><a href=\"https:\/\/gist.github.com\/yongboy\/3945295#file-tcp_listener-erl\">tcp_listener.erl<\/a> hosted with \u2764 by <a href=\"https:\/\/github.com\/\">GitHub<\/a><\/div>\n<\/div>\n<\/div>\n<p>\u5f88\u663e\u7136\uff0c\u63a5\u6536\u5ba2\u6237\u7aef\u7684\u8fde\u63a5\u4e4b\u540e\uff0c\u8f6c\u4ea4\u7ed9tcp_client_handler\u6a21\u5757\u8fdb\u884c\u5904\u7406\uff1a<\/p>\n<div id=\"gist3945302\" class=\"gist\">\n<div class=\"gist-file\">\n<div class=\"gist-data gist-syntax\">\n<div class=\"file-data\">\n<table class=\"lines highlight\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"line-numbers\"><\/td>\n<td class=\"line-data\">\n<div id=\"file-tcp_client_handler-erl-LC1\" class=\"line\">&#8211;<span class=\"pl-k\">module<\/span>(<span class=\"pl-en\">tcp_client_handler<\/span>).<\/div>\n<div id=\"file-tcp_client_handler-erl-LC2\" class=\"line\">&#8211;<span class=\"pl-k\">behaviour<\/span>(<span class=\"pl-en\">gen_server<\/span>).<\/div>\n<div id=\"file-tcp_client_handler-erl-LC3\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">start_link<\/span>\/<span class=\"pl-c1\">1<\/span>]).<\/div>\n<div id=\"file-tcp_client_handler-erl-LC4\" class=\"line\">&#8211;<span class=\"pl-k\">export<\/span>([<span class=\"pl-en\">init<\/span>\/<span class=\"pl-c1\">1<\/span>, <span class=\"pl-en\">handle_call<\/span>\/<span class=\"pl-c1\">3<\/span>, <span class=\"pl-en\">handle_cast<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">handle_info<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">terminate<\/span>\/<span class=\"pl-c1\">2<\/span>, <span class=\"pl-en\">code_change<\/span>\/<span class=\"pl-c1\">3<\/span>]).<\/div>\n<div id=\"file-tcp_client_handler-erl-LC5\" class=\"line\">&#8211;<span class=\"pl-k\">record<\/span>(<span class=\"pl-en\">state<\/span>, {<span class=\"pl-vo\">socket<\/span>, <span class=\"pl-vo\">addr<\/span>}).<\/div>\n<div id=\"file-tcp_client_handler-erl-LC6\" class=\"line\">&#8211;<span class=\"pl-k\">define<\/span>(<span class=\"pl-en\">TIMEOUT<\/span>, <span class=\"pl-c1\">120000<\/span>).<\/div>\n<div id=\"file-tcp_client_handler-erl-LC7\" class=\"line\"><\/div>\n<div id=\"file-tcp_client_handler-erl-LC8\" class=\"line\"><span class=\"pl-en\">start_link<\/span>(<span class=\"pl-vo\">Socket<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_client_handler-erl-LC9\" class=\"line\"><span class=\"pl-en\">gen_server<\/span>:<span class=\"pl-en\">start_link<\/span>(<span class=\"pl-k\">?<\/span><span class=\"pl-en\">MODULE<\/span>, [<span class=\"pl-vo\">Socket<\/span>], []).<\/div>\n<div id=\"file-tcp_client_handler-erl-LC10\" class=\"line\"><\/div>\n<div id=\"file-tcp_client_handler-erl-LC11\" class=\"line\"><span class=\"pl-en\">init<\/span>([<span class=\"pl-vo\">Socket<\/span>]) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_client_handler-erl-LC12\" class=\"line\"><span class=\"pl-en\">inet<\/span>:<span class=\"pl-en\">setopts<\/span>(<span class=\"pl-vo\">Socket<\/span>, [{<span class=\"pl-c1\">active<\/span>, <span class=\"pl-c1\">once<\/span>}, {<span class=\"pl-c1\">packet<\/span>, <span class=\"pl-c1\">2<\/span>}, <span class=\"pl-c1\">binary<\/span>]),<\/div>\n<div id=\"file-tcp_client_handler-erl-LC13\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, {<span class=\"pl-vo\">IP<\/span>, <span class=\"pl-vo\">_Port<\/span>}} <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">inet<\/span>:<span class=\"pl-en\">peername<\/span>(<span class=\"pl-vo\">Socket<\/span>),<\/div>\n<div id=\"file-tcp_client_handler-erl-LC14\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">socket<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">Socket<\/span>, <span class=\"pl-vo\">addr<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">IP<\/span>}}.<\/div>\n<div id=\"file-tcp_client_handler-erl-LC15\" class=\"line\"><\/div>\n<div id=\"file-tcp_client_handler-erl-LC16\" class=\"line\"><span class=\"pl-en\">handle_call<\/span>(<span class=\"pl-vo\">Request<\/span>, <span class=\"pl-vo\">From<\/span>, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_client_handler-erl-LC17\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<div id=\"file-tcp_client_handler-erl-LC18\" class=\"line\"><\/div>\n<div id=\"file-tcp_client_handler-erl-LC19\" class=\"line\"><span class=\"pl-en\">handle_cast<\/span>(<span class=\"pl-vo\">Msg<\/span>, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_client_handler-erl-LC20\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<div id=\"file-tcp_client_handler-erl-LC21\" class=\"line\"><\/div>\n<div id=\"file-tcp_client_handler-erl-LC22\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>({<span class=\"pl-c1\">tcp<\/span>, <span class=\"pl-vo\">Socket<\/span>, <span class=\"pl-vo\">Data<\/span>}, <span class=\"pl-vo\">State<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_client_handler-erl-LC23\" class=\"line\"><span class=\"pl-en\">inet<\/span>:<span class=\"pl-en\">setopts<\/span>(<span class=\"pl-vo\">Socket<\/span>, [{<span class=\"pl-c1\">active<\/span>, <span class=\"pl-c1\">once<\/span>}]),<\/div>\n<div id=\"file-tcp_client_handler-erl-LC24\" class=\"line\"><span class=\"pl-en\">io<\/span>:<span class=\"pl-en\">format<\/span>(<span class=\"pl-s1\"><span class=\"pl-pds\">&#8220;<\/span><span class=\"pl-c1\">~p<\/span> got message <span class=\"pl-c1\">~p<\/span><span class=\"pl-cce\">\\n<\/span><span class=\"pl-pds\">&#8220;<\/span><\/span>, [<span class=\"pl-en\">self<\/span>(), <span class=\"pl-vo\">Data<\/span>]),<\/div>\n<div id=\"file-tcp_client_handler-erl-LC25\" class=\"line\"><span class=\"pl-c1\">ok<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">send<\/span>(<span class=\"pl-vo\">Socket<\/span>, &lt;&lt;<span class=\"pl-s1\"><span class=\"pl-pds\">&#8220;<\/span>Echo back : <span class=\"pl-pds\">&#8220;<\/span><\/span>, <span class=\"pl-vo\">Data<\/span>\/<span class=\"pl-st\">binary<\/span>&gt;&gt;),<\/div>\n<div id=\"file-tcp_client_handler-erl-LC26\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-vo\">State<\/span>};<\/div>\n<div id=\"file-tcp_client_handler-erl-LC27\" class=\"line\"><\/div>\n<div id=\"file-tcp_client_handler-erl-LC28\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>({<span class=\"pl-c1\">tcp_closed<\/span>, <span class=\"pl-vo\">Socket<\/span>}, <span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">addr<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">Addr<\/span>} <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">StateData<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_client_handler-erl-LC29\" class=\"line\"><span class=\"pl-en\">error_logger<\/span>:<span class=\"pl-en\">info_msg<\/span>(<span class=\"pl-s1\"><span class=\"pl-pds\">&#8220;<\/span><span class=\"pl-c1\">~p<\/span> Client <span class=\"pl-c1\">~p<\/span> disconnected.<span class=\"pl-cce\">\\n<\/span><span class=\"pl-pds\">&#8220;<\/span><\/span>, [<span class=\"pl-en\">self<\/span>(), <span class=\"pl-vo\">Addr<\/span>]),<\/div>\n<div id=\"file-tcp_client_handler-erl-LC30\" class=\"line\">{<span class=\"pl-c1\">stop<\/span>, <span class=\"pl-c1\">normal<\/span>, <span class=\"pl-vo\">StateData<\/span>};<\/div>\n<div id=\"file-tcp_client_handler-erl-LC31\" class=\"line\"><\/div>\n<div id=\"file-tcp_client_handler-erl-LC32\" class=\"line\"><span class=\"pl-en\">handle_info<\/span>(<span class=\"pl-vo\">_Info<\/span>, <span class=\"pl-vo\">StateData<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_client_handler-erl-LC33\" class=\"line\">{<span class=\"pl-c1\">noreply<\/span>, <span class=\"pl-vo\">StateData<\/span>}.<\/div>\n<div id=\"file-tcp_client_handler-erl-LC34\" class=\"line\"><\/div>\n<div id=\"file-tcp_client_handler-erl-LC35\" class=\"line\"><span class=\"pl-en\">terminate<\/span>(<span class=\"pl-vo\">_Reason<\/span>, <span class=\"pl-k\">#<\/span><span class=\"pl-en\">state<\/span>{<span class=\"pl-vo\">socket<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-vo\">Socket<\/span>}) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_client_handler-erl-LC36\" class=\"line\">(<span class=\"pl-k\">catch<\/span> <span class=\"pl-en\">gen_tcp<\/span>:<span class=\"pl-en\">close<\/span>(<span class=\"pl-vo\">Socket<\/span>)),<\/div>\n<div id=\"file-tcp_client_handler-erl-LC37\" class=\"line\"><span class=\"pl-c1\">ok<\/span>.<\/div>\n<div id=\"file-tcp_client_handler-erl-LC38\" class=\"line\"><\/div>\n<div id=\"file-tcp_client_handler-erl-LC39\" class=\"line\"><span class=\"pl-en\">code_change<\/span>(<span class=\"pl-vo\">OldVsn<\/span>, <span class=\"pl-vo\">State<\/span>, <span class=\"pl-vo\">Extra<\/span>) <span class=\"pl-k\">-&gt;<\/span><\/div>\n<div id=\"file-tcp_client_handler-erl-LC40\" class=\"line\">{<span class=\"pl-c1\">ok<\/span>, <span class=\"pl-vo\">State<\/span>}.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"gist-meta\"><a href=\"https:\/\/gist.github.com\/yongboy\/3945302\/raw\/tcp_client_handler.erl\">view raw<\/a><a href=\"https:\/\/gist.github.com\/yongboy\/3945302#file-tcp_client_handler-erl\">tcp_client_handler.erl<\/a> hosted with \u2764 by <a href=\"https:\/\/github.com\/\">GitHub<\/a><\/div>\n<\/div>\n<\/div>\n<p>\u548c\u6807\u51c6API\u5bf9\u6bd4\u4e00\u4e0b\uff0c\u53ef\u4ee5\u611f\u53d7\u5230\u5f02\u6b65IO\u7684\u597d\u5904\u3002<\/p>\n<h2><strong>\u5c0f\u7ed3<\/strong><\/h2>\n<p>\u901a\u8fc7\u4e0d\u540c\u7684\u6a21\u5f0f\uff0c\u7b80\u5355\u5b9e\u73b0\u4e00\u4e2a\u57fa\u4e8eErlang OTP\u7684TCP\u670d\u52a1\u5668\uff0c\u4e5f\u662f\u5b66\u4e60\u603b\u7ed3\uff0c\u4e0d\u81f3\u4e8e\u5fd8\u8bb0\u3002<\/p>\n<p>\u60a8\u82e5\u6709\u66f4\u597d\u7684\u5efa\u8bae\uff0c\u6b22\u8fce\u544a\u77e5\uff0c\u8c22\u8c22\u3002<\/p>\n<p>link:<a title=\"http:\/\/www.blogjava.net\/yongboy\/archive\/2012\/10\/24\/390185.html\" href=\"http:\/\/www.blogjava.net\/yongboy\/archive\/2012\/10\/24\/390185.html\" target=\"_blank\">\u00a0http:\/\/www.blogjava.net\/yongboy\/archive\/2012\/10\/24\/390185.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5957\u63a5\u5b57\u6a21\u5f0f \u4e3b\u52a8\u6a21\u5f0f\uff08\u9009\u9879{active, true}\uff09\u4e00\u822c\u8ba9\u4eba\u5f88\u559c\u6b22\uff0c\u975e\u963b\u585e\u6d88\u606f\u63a5\u6536\uff0c\u4f46\u5728\u7cfb\u7edf\u65e0\u6cd5\u5e94\u5bf9\u8d85\u5927\u6d41 <span class=\"ellipsis\">&hellip;<\/span> <span class=\"more-link-wrap\"><a href=\"https:\/\/www.yanbin888.com\/?p=98\" class=\"more-link\"><span>Read More &rarr;<\/span><\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16],"tags":[27],"class_list":["post-98","post","type-post","status-publish","format-standard","hentry","category-erlang","tag-erlang"],"_links":{"self":[{"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/posts\/98","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=98"}],"version-history":[{"count":2,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/posts\/98\/revisions"}],"predecessor-version":[{"id":100,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/posts\/98\/revisions\/100"}],"wp:attachment":[{"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=98"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=98"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=98"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}