精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-04
最后修改:2009-06-04
代码: -module(binary_server). -export([start/0]). start() -> {ok,Listen}=gen_tcp:listen(7777,[binary,{packet,0},{reuseaddr,true},{active,true}]), register(kvs,spawn(fun() -> dict() end)), accept(Listen). accept(Listen) -> {ok,Socket}=gen_tcp:accept(Listen), spawn(fun() -> accept(Listen) end), inet:setopts(Socket,[binary,{packet,0},{active,true}]), process(Socket,<<>>). process(Socket,Left) -> receive {tcp,Socket,Bin} -> Buffer=list_to_binary(binary_to_list(Left) ++ binary_to_list(Bin)), case regonized(Buffer) of {save_ok,RealRemaning} -> Resp=[16#81,16#1] ++ fill_all(0,22,[]), gen_tcp:send(Socket,list_to_binary(Resp)), process(Socket,RealRemaning); {get_ok,undefined,Remaining} -> Value= <<"not_found">>, BodyLen=length(binary_to_list(Value))+4, Resp=[16#81] ++ fill_all(0,3,[]) ++[16#4] ++ fill_all(0,3,[]) ++ binary_to_list(<<BodyLen:32>>) ++ binary_to_list(<<0:128>>) ++ binary_to_list(Value), gen_tcp:send(Socket,list_to_binary(Resp)), process(Socket,Remaining); {get_ok,{ok,Value},Remaining} -> BodyLen=length(binary_to_list(Value))+4, Resp=[16#81] ++ fill_all(0,3,[]) ++[16#4] ++ fill_all(0,3,[]) ++ binary_to_list(<<BodyLen:32>>) ++ binary_to_list(<<0:128>>) ++ binary_to_list(Value), gen_tcp:send(Socket,list_to_binary(Resp)), process(Socket,Remaining); {get_timeout,Remaining} -> process(Socket,Remaining); {not_engouh_streams} -> process(Socket,Buffer) end; {tcp_closed,Socket} -> io:format("peer closed~n") end. regonized(Buffer) -> case Buffer of %%set command <<16#80:8,16#1:8,KeyLen:16/big, ExtraLen:8/big,DataType:8,Reserved:16/big, BodyLen:32/big,Opaque:32/big,Cas:64/big, Extras:64/big,Key:KeyLen/big-binary-unit:8, Remaning/binary>> -> ValueLen=BodyLen-KeyLen-ExtraLen, case Remaning of <<Value:ValueLen/binary-unit:8, RealRemaning/binary>> -> %% got completed packet,deal with set command kvs ! {self(),{store,Key,Value}}, {save_ok,RealRemaning}; <<_/binary>> -> %% not enough streams {not_enough_streams} end; %%get command <<16#80:8,16#0:8,KeyLen:16/big,16#0:8, DataType:8,Reserved:16/big,BodyLen:32/big, Opaque:32/big,Cas:64/big,Key:KeyLen/big-binary-unit:8, Remaining/binary>> -> kvs ! {self(),{lookup,Key}}, receive {lookup,Value} -> {get_ok,Value,Remaining} after 1000 -> {get_timeout,Remaining} end; %% no match <<_/binary>> -> {not_engouh_streams} end. dict() -> receive {From,{store,Key,Value}} -> put(Key,{ok,Value}), dict(); {From,{lookup,Key}} -> From ! {lookup,get(Key)}, dict() end. debug_print([H|T]) -> io:format("~w,",[H]), debug_print(T); debug_print([])-> ok. fill_all(C,0,L)-> L; fill_all(C,N,L)-> N1=N-1, L1=[C|L], fill_all(C,N1,L1). 说明: 1. 16#80:8 16#代表16进制,80是memcached协议头的第一个字节 80代表request 具体协议内容memcached官网上有很详尽的解释 2. KeyLen:16/big 协议中key的长度是占2个字节 ,16是bit数 . 因为多于一个字节的数据在存储和传输时就会涉及字节序问题, 这里big代表的是大端/网络字节序, 因为我的测试client在传输数据前已经将数据转成网络字节序,所以这里接收必须是big 3. Key:KeyLen/big-binary-unit:8 , 这里Key具体的字节数是由之前得到的KeyLen指定的,所以表示为Key:KeyLen, 因为这里的单位应该是字节,所以需要指定为unit:8,其实这里指定了binary binary类型默认的unit就是8,即 实际的size = KeyLen * unit 个 bit 4. lookup没有找到指定key对应value时,这里没有按协议处理,以not_found为value返回给client,实际协议是返回一个status为非0的协议包 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-06-04
大牛啊,,,
erlang的语法好怪,,以后一定要学学``` |
|
返回顶楼 | |
发表时间:2009-06-04
willko 写道 大牛啊,,,
erlang的语法好怪,,以后一定要学学``` 大牛是yufeng,litaocheng他们,我也准备基础好点了,再去骚扰他们,呵呵 |
|
返回顶楼 | |
发表时间:2009-06-04
我们组的项目核心是用erlang做的,可惜我不会,有空一定要去学学。
|
|
返回顶楼 | |
发表时间:2009-06-05
binary确实很强大 还有bianry list comprehension 不要忘记了哦
|
|
返回顶楼 | |
发表时间:2009-06-05
前段时间也要用Erlang和memcached通信,在网上找了个,写的好复杂,
就放弃了,改成和PHP socket server通信 来解决 你这段代码也没有说明如何散列访问,我们那些memcache都是散列在多台的 |
|
返回顶楼 | |
发表时间:2009-06-05
mryufeng 写道 binary确实很强大 还有bianry list comprehension 不要忘记了哦
好的,回头好好研究下 |
|
返回顶楼 | |
发表时间:2009-06-05
美洲豹 写道 前段时间也要用Erlang和memcached通信,在网上找了个,写的好复杂,
就放弃了,改成和PHP socket server通信 来解决 你这段代码也没有说明如何散列访问,我们那些memcache都是散列在多台的 我就是想试试binary的语法而已,整好拿memcached protocol做个试验而已 这个程序离一个真正的memcached client可差远了,估计有很多地方都是 Don't do this的典范,呵呵 |
|
返回顶楼 | |
发表时间:2009-06-06
andrew913 写道 我们组的项目核心是用erlang做的,可惜我不会,有空一定要去学学。
用于实现什么功能? |
|
返回顶楼 | |
发表时间:2009-06-06
willko 写道 大牛啊,,,
erlang的语法好怪,,以后一定要学学``` 以后我也学学 ~!~ |
|
返回顶楼 | |