基于erlang语言的socket通信

来源:互联网 发布:涌泉知恩 编辑:程序博客网 时间:2024/05/22 00:54

erlang语言实现socket聊天室

关键词

  • erlang

  • socket

erlang语言是函数式编程语言,由Erlang之父Joe Amstrong编写出erlang原型,并在爱立信公司得到大规模应用,进而在通信行业有了一席之地,其优势在于高并发性、容错、高性能。
socket是实现数据交互的最普遍的方式,Erlang/OTP中也融合了tcp协议,并通过OTP中的库简单的编程就能实现服务端、客户端的通信,现在我们自己来实现编写服务器和客户端。
什么都不多说了,先上菜再解释
  • 服务器端
-module (server).-export ([start/0]).-define (tcp_opts, [binary, {active,true}, {packet, 0},{reuseaddr, true}]).%% 宏定义,当代码读到?errorlog,会用io:format("errorlog point")代替-define (errorlog, io:format("errorlog point~n")).start() ->    start(8888).start(Port) ->    {ok, ListenSocket} = gen_tcp:listen(Port, ?tcp_opts),    register(server, spawn(fun() -> server_conn(ListenSocket) end)),    server_conn(ListenSocket).server_conn(ListenSocket) ->    case gen_tcp:accept(ListenSocket) of        {ok, Socket} ->            io:format("connect succeed:~p~n",[Socket]),            server_route();        {error, Reason} ->            io:format("Socket closed : ~p~n",[Reason])    end.server_route() ->    receive        {tcp, Socket, Data} ->            ?errorlog,            gen_tcp:send(Socket, Data);        {tcp_closed, Socket} ->            gen_tcp:close(Socket)    end.
  • 客户端
-module (client).-export ([start/0]).-define (tcp_opts, [binary, {packet, 0},{active, true}]).start() ->    start("localhost",8888).start(IP,Port) ->    register(client, spawn(fun() -> conn_client(IP,Port) end)).conn_client(IP,Port) ->    case gen_tcp:connect(IP, Port, ?tcp_opts) of        {ok, Socket} ->            send_msg(Socket),            do_handle_client(Socket),            io:format("connection successed! ~w~n",[Socket]),            conn_client(IP,Port);        {error, Reason} ->            io:format("connect failed! ~n"),            exit(Reason)    end.do_handle_client(Socket) ->    receive        {tcp, Socket, Packet} ->            recv_msg(Packet),            do_handle_client(Socket);        {tcp_closed, Socket} ->            gen_tcp:close(Socket)    end.recv_msg(Packet) ->    Msg= binary_to_term(Packet),    io:format("Received Msg: ~p~n", [Msg]).send_msg(Socket) ->    Msg = io:get_line('Input Your Msg:'),    Pack = term_to_binary(Msg),    io:format("Your msg: ~p~n", [Msg]),    gen_tcp:send(Socket, Pack),    send_msg(Socket).

在服务端中定义了start函数并把端口Port绑定为8888(和客户端对应端口),在第三步用gen_tcp模块的accept函数返回一个Socket进程(Java是说实例化了一个socket),接着在请求连接的下一个函数定义了接收进程(注意:register中启动了一个进程,这个就是接收进程),然后按照这些步骤定义之后,在Erlang shell打印输出:

服务端(要启动两个窗口,one for server,another for client)
1>server:start().
客户端
1>client:start().

运行结果如下所示:
这里写图片描述
这里写图片描述