Erlang gen_tcp和gen_server结合应用

今天把 tcp和gen_server结合在一起使用。

个人猜想:erlang的OTP模式,gen_server,handle_call处理代码逻辑,handle_info处理发给server的消息,模块内,提供接口函数,供外部调用 gen_server:call()..

erlang进程通信用 !发送消息。 消息接收应该是在handle_info处接收。 (这些结论有待验证..只是猜想。)

-module(myserver).

-behaviour(gen_server).

%%define
-define(POLICY_PORT,8080). %%监听端口
-define(TCP_OPTION,[
					binary,
					{packet,0},
					{active,false},
					{reuseaddr, true}
					]).
%% ====================================================================
%% API functions
%% ====================================================================
-export([start_link/0,start_server/0,loop/1,sendMSG/2,test_info/0]).

%%%gen_server callback
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

init([])->
	 process_flag(trap_exit, true),
	 %%{ok, test_info()}.
	 start_server().

handle_call({data,_Data,_PID},_From,_State)->
	io:format("call~p~n",[_Data]),
	Reply = _Data,
	sendMSG(_Data,_PID),
	%%{reply,Reply,_State};
	{reply,Reply,Reply};
handle_call(_Request,_From,_State)->
	Reply = ok,
	{reply,Reply,_State}.

handle_cast(_Msg,_State) ->
	{noreply,_State}.

handle_info({'_EXIT',_Pid,_Reason},_State)->
	{noreply,_State};
handle_info({data,_Data,_CSock},_State) ->
	case gen_tcp:send(_CSock,_Data) of
		 ok ->
			io:format("client MSG = ~p~n",[_Data]);
		{error,Reason} ->
			io:format("client Error~p~n",[Reason])
	end,
	{noreply,_State};
handle_info({tcp_closed,Socket},State)->
	io:format("client sockt closed ~p~n",[Socket]),
	{noreply,State};
handle_info(_Info,_State) ->
	{noreply,_State}.

terminate(_Reason,_State) ->
	ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

%% ====================================================================
%% Internal functions
%% ====================================================================

start_link() ->
	gen_server:start_link({local,?MODULE}, ?MODULE, [], []).

start_server() ->
	case gen_tcp:listen(?POLICY_PORT, ?TCP_OPTION) of
		 {ok,LSock} ->
				%%io:format("listen ok~p~n", []),
				spawn(?MODULE,loop,[LSock]),
				{ok,LSock};
		{error,Reason} ->
  				{stop,Reason}
    end.

loop(LSock) ->
    case gen_tcp:accept(LSock) of 
		{ok,CSock} ->
			get_Recv(CSock);
			%%{ok,CSock};
		{error,Reason} ->
			Reason
	end,
	loop(LSock).

get_Recv(CSock) ->
	case gen_tcp:recv(CSock, 0) of
		{ok,Data} ->
			io:format("get receive ~p~n", [Data]),
			%%gen_tcp:send(CSock, Data), %%采用gen_server call 
			gen_server:call(?MODULE,{data,Data,CSock}),
			%%gen_server:call(CSock,{data,Data}),
			get_Recv(CSock);
		_->
			error
	end.

sendMSG(Data,PID) ->
	self()!{data,Data,PID}.

test_info()->
	io:format("~p~n", [self()]).













client:

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.Socket;
	import flash.utils.ByteArray;
	
	public class MySocket extends Sprite
	{
		private static const port:int = 8080;
		private static const ip:String = "127.0.0.1";
		
		private var socket:Socket;
		public function MySocket()
		{
			socket = new Socket();
			socket.connect(ip,port);
			
			socket.addEventListener(Event.CLOSE, closeHandler);
			socket.addEventListener(Event.CONNECT, connectHandler);
			socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
		}
		
		private function closeHandler(e:Event):void
		{
			trace("connect close");
		}
		
		private function connectHandler(e:Event):void
		{
			trace("connect ok");
			socket.writeInt(6);
			socket.flush();
		}
		
		private function ioErrorHandler(e:IOErrorEvent):void
		{
			trace(e.errorID);
		}
		
		private function securityErrorHandler(e:SecurityErrorEvent):void
		{
			
		}
		
		private function socketDataHandler(e:ProgressEvent):void
		{
			trace("得到数据")
			var msg:int = socket.readInt();
			trace(msg.toString());
		}
	}
}


你可能感兴趣的:(erlang)