[Erlang之旅 0009] socket 通讯

前面学习完了gen_server 、gen_tcp 现在做一个简易的socket通讯,服务端将接收到的信息返回给客户端,具体代码如下:

服务端:

 1 -module(tcp_socket3).
 2 -behaviour(gen_server).
 3
 4 -export([start/0, login/2, stop/0]).
 5 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
 6
 7 -export([start_client/0]).
 8
 9 -record(users, {id, name, pwd}).
10
11 start() ->
12     start(6000).
13
14 start(Port) ->
15     gen_server:start_link({local, ?MODULE}, ?MODULE, [], []),
16     {ok, ListenSocket} = gen_tcp:listen(Port, [binary,{packet, 0}, {active, true}]),
17     par_connect(ListenSocket).
18
19 init([]) ->
20     ets:new(?MODULE, [set, public, named_table, {keypos, #users.id}]),
21
22     {ok, ?MODULE}.
23
24 par_connect(Listen) ->
25     {ok, Socket} = gen_tcp:accept(Listen),
26     spawn(fun() -> par_connect(Listen) end),
27     loop(Socket).
28
29 loop(Socket) ->
30     receive
31         {tcp, Socket, Data} ->
32             io:format("Server receive binary:~p~n", [Data]),
33             RecStr = binary_to_list(Data),
34             io:format("Server receive binary_to_list:~p~n",[RecStr]),
35             gen_tcp:send(Socket, Data),
36             loop(Socket);
37         {tcp_closed, Socket} ->
38             io:format("Client socket closed")
39     end.
40
41
42 login(Id,Pwd) ->
43     gen_server:call(?MODULE,{login, Id, Pwd}).
44
45 stop() ->
46     gen_server:call(?MODULE, stop).
47
48 handle_call({login, Id, Pwd}, _From, Tab) ->
49     Reply = case ets:lookup(Tab, Id) of
50         [] -> User1=#users{id=Id, name=Id, pwd=Pwd},
51             ets:insert(Tab, User1),
52             io:format("Tab content:~p~n",[ets:tab2list(Tab)])
53     end,
54     {reply, Reply, Tab};
55 handle_call(stop, _From, Tab) ->
56     {stop, normal, stopped, Tab}.
57
58 handle_cast(_Msg, State) -> {noreply, State}.
59 handle_info(_Info, State) -> {noreply, State}.
60 terminate(_Reason, State) ->
61     ok.
62
63 code_change(_OldVsn, State, _Extra) -> {ok, State}.
64
65 start_client() ->
66     start_client("localhost", 6000).
67
68 start_client(Address, Port) ->
69     {ok, Socket} = gen_tcp:connect(Address, Port, [binary, {packet, 0}, {active, true}]),
70      ok=gen_tcp:send(Socket, list_to_binary("{login,tom, tom1}")),
71      receive
72          {tcp, Socket, Data} ->
73               io:format("Client receive binary:~p~n", [Data]),
74               RecStr = binary_to_list(Data),
75               io:format("Client receive binary_to_list:~p~n", [RecStr]),
76               gen_tcp:close(Socket)
77         end.

客户端:

 1 -module(tcp_client).
 2 -behaviour(gen_server).
 3
 4 -export([start/0, start/2, stop/0, send_data/1]).
 5 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
 6
 7 -define(HOSTIP,"127.0.0.1").
 8 -define(PORT, 8000).
 9
10 -record(state, {socket}).
11
12 start() ->
13     start(?HOSTIP, ?PORT).
14
15 start(HOSTIP, PORT) ->
16     gen_server:start_link({local, ?MODULE}, ?MODULE,[HOSTIP, PORT], []).
17
18 init([HostIP, Port]) ->
19     case gen_tcp:connect(HostIP, Port, [binary, {packet, 0}, {active, true}]) of
20         {ok, Socket} ->
21             io:format("Connect host success, start to receive message:~n"),
22             spawn(fun() ->loop(Socket) end),
23             {ok, #state{socket = Socket}};
24         {error, Reason} ->
25             io:format("Connect host error:~p~n", [Reason]),
26             {stop, Reason}
27     end.
28
29
30 loop(Socket) ->
31     io:format("loop start ~n"),
32     receive
33         {tcp, Socket, Data} ->
34             io:format("Client receive binary:~p~n", [Data]),
35             loop(Socket);
36         {tcp_closed, Socket} ->
37             io:format("Client is closed~n"),
38             stop()
39     end.
40
41 stop() ->
42     gen_server:cast(?MODULE, stop).
43
44 send_data(Msg) ->
45     gen_server:call(?MODULE,Msg).
46
47 handle_call(Msg, _From, State) ->
48     Reply = gen_tcp:send(State#state.socket, list_to_binary(Msg)),
49     {reply,Reply, State}.
50 handle_cast(stop, State) ->
51     {stop, normal, State}.
52 handle_info({tcp,Socket, RawData}, State) ->
53     io:format("Client receive msg:~p~n", [RawData]),      %% 处理接收到的信息
54     {noreply, State};
55 handle_info({tcp_closed, _Socket}, State) ->
56     stop(),
57     {noreply, State}.
58 terminate(_Reason, _State) ->
59     ok.
60 code_change(_OldVsn, State, Extra) ->
61     {ok, State}.

运行服务端:

2> c(tcp_socket3).
tcp_socket3.erl:60: Warning: variable ‘State‘ is unused
{ok,tcp_socket3}
3> tcp_socket3:start().
Server receive binary:<<"abcdaeafad">>
Server receive binary_to_list:"abcdaeafad"

运行客户端:

8> tcp_client:start("127.0.0.1", 6000).
Connect host success, start to receive message:
loop start
{ok,<0.52.0>}
9> tcp_client:send_data("abcdaeafad").
ok
Client receive msg:<<"abcdaeafad">>

[Erlang之旅 0009] socket 通讯,布布扣,bubuko.com

时间: 2024-12-20 11:33:50

[Erlang之旅 0009] socket 通讯的相关文章

客户端技术的一点思考(数据存储用SQLite, XMPP通讯用Gloox, Web交互用LibCurl, 数据打包用Protocol Buffer, socket通讯用boost asio)

今天看到CSDN上这么一篇< 彻底放弃没落的MFC,对新人的忠告!>, 作为一个一直在Windows上搞客户端开发的C++程序员,几年前也有过类似的隐忧(参见 落伍的感觉), 现在却有一些不同的想法. 首先,个人职业发展是否成功, 技术只是其中一小块,尤其是在大公司, 更多的是依靠所谓的软实力.作为一个对技术有追求的工匠,我们下面重点说技术相关的. 现在回头看计算机行业的发展,我们看到不同的发展阶段: 1. PC时代,这个时代离我们并不遥远, 也有是2000年前后, 该时代最鲜明的特征是Win

iOS开发socket通讯

写写socket通讯那些事儿.     socket通讯公司用于给服务器发一些指令用于控制智能家居类的设备.socket无非就是发过来发过去,至于具体内容跟服务器协商就好.接下来先说说与socket通讯配合使用的socket Tool 的mac 工具.首先打开工具(工具连接以及socket用到的文件:SocketToolfor_mac_and_Third_for_xocde_socket.zip)选择Tcp Server 然后点击创建 端口号输入一个数字,60000 把. 注意可能完成之后这个数

试解析Tomcat运行原理(一)--- socket通讯

关于这篇文章也确实筹划了很久,今天决定开篇写第一篇,说起tomcat首先很容易联想到IIS,因为我最开始使用的就是.net技术,我第一次使用asp写学生成绩管理系统后,很茫然如何让别人都能看到或者说使用这个系统呢?由此认识了IIS,它是一个web容器,天生的多线程,及时响应用户提交的请求返回html页面,这就是我了解的最初的web容器的功能,由此我们来认识tomcat也并不困难,可以的话,在了解完tomcat后我们可以继续了解jboss.jetty等,好我们进入主题. 我们在平时开发的过程中是在

[Erlang之旅 0005] ETS 和Record

ETS 提供“键-值” 搜索表, 驻留在内存中,速度较快.是缓存的大利器. record 作为erlang的一种数据结构,通常用于函数量传递. ETS中创建表, 对数据进行增.删.改.查 , 及关闭表常用的函数 ets:new(Name, Options) -> tid()   %% 创建表 Options: Type: set | ordered_set | bag | duplicate_bag set: 每一个元组的键值都不能相同:ordered_set:元组键不能相同,并且会进行排序 b

[Erlang之旅 0008] string 常用函数

参考文档:http://www.erlang.org/erldoc?q=string%3Bright&x=-967&y=-384 string类型,经常用到,所有练习一下: 3> string:len("fan"). %% 字符串长度 3 4> string:len("你的"). 2 5> string:len("fan你的中国"). 7 6> string:equal("an",&qu

c# TCP Socket通讯基础

在做网络通讯方面的程序时,必不可少的是Socket通讯. 那么我们需要有一套既定的,简易的通讯流程. 如下: <pre name="code" class="csharp">public class PublicSocket { public const string DOWNLOAD_STATUS_WAIT = "1"; public const string DOWNLOAD_STATUS_PAUSE = "2"

windows 与 Linux SOCKET通讯

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 windows client 端口 // Def_win_client_socket_test.cpp :

Java Socket通讯---网络基础

java socket 通讯 参考慕课网:http://www.imooc.com/learn/161 一.网络基础知识 1.1 通讯示意图 1.2 TCP/IP协议 TCP/IP是世界上应用最为广泛的协议 是以TCP/IP为基础的不同层次上多个协议的集合 也称TCP/IP协议簇 或 TCP/IP协议栈 TCP:Transmission Control Protocol, 传输控制协议 IP:Internet Protocol,互联网协议 1.3 TCP/IP模型 1.4 IP地址 为实现网络中

Socket通讯简图

Socket通讯简图: