今天把 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()]).
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());
}
}
}