基于erlang语言的socket通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qqqrtretretee/article/details/76863101

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().

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

猜你喜欢

转载自blog.csdn.net/qqqrtretretee/article/details/76863101