服务器代码:tcp_server.erl
-module(tcp_server). -compile(export_all). -define(TCP_OPT, [binary, {packet, 4}, {reuseaddr,true}, {active, true}]). %% binary 设置通信数据格式,可以通过简单的term_to_binary编码, binary_to_term解码 %% {packet, 4} 每个报文从一个4字节长的头开始 %% {reuseaddr, true} 端口复用 %% {active, true} 主动套接字(非阻塞) %% {active,false} 被动套接字(阻塞) %% {active,once} 主动套接字仅接受一条信息,要想接受下一条必须再次激活(半阻塞) start_server() -> {ok, ListenSocket} = gen_tcp:listen(8888, ?TCP_OPT), %% 监听8888端口 io:format(" listen socket :~p~n", [ListenSocket]), {ok, Socket} = gen_tcp:accept(ListenSocket), %% 程序挂起,等待连接 io:format(" accept socket :~p~n", [Socket]), gen_tcp:close(ListenSocket),%% 关闭监听,服务器无法再建立新的连接 %% 不影响已有的socket通信 loop(Socket). loop(Socket) -> receive {tcp, Socket, Bin} -> io:format("receive bin data: ~p~n",[Bin]), Str = binary_to_term(Bin), io:format("unpack data: ~w~n",[Str]), Reply = {9999,9999000}, io:format("server reply: ~p~n", [Reply]), gen_tcp:send(Socket, term_to_binary(Reply)), loop(Socket); {tcp_closed, Socket} -> io:format("socket closed: ~p~n",[Socket]) after 3000 -> %% 超时关闭socket gen_tcp:close(Socket) end.
客户端代码:tcp_client.erl
-module(tcp_client). -export([test_tcp/0]). test_tcp() -> {ok, Socket} = gen_tcp:connect("localhost", 8888, [binary, {packet, 4}]), io:format("listen socket:~p~n",[Socket]), SendData = term_to_binary({10,12}), Data2 = term_to_binary({56,12}), %% 发送了两次数据,是为了验证: %% 服务端关闭了listensocket,并不影响已有的socket ok = gen_tcp:send(Socket, SendData), ok = gen_tcp:send(Socket, Data2), loop(Socket). loop(Socket) -> receive {tcp, Socket, Bin} -> io:format("receive bin data: ~p~n",[Bin]), Val = binary_to_term(Bin), io:format("receive data: ~p~n",[Val]), loop(Socket); {tcp_closed, Socket} -> io:format("socket closed :~p~n",[Socket]) end.
执行服务端代码:
erlc tcp_server.erl erl tcp_server:start_server().
执行客户端代码:
erlc tcp_client.erl erl tcp_client:test_tcp().
服务端结果:
客户端结果: