2011-08-19 60 views
0

我在这里做了一个服务器,它从终端接收消息。我想要做的是当服务器收到来自终端的消息时,它应该将它写入文件中。但我不知道我该怎么做。我想在接收函数中写入文件方法file:open,file:write,但它没有按照我的想法工作。recv消息并写入文件

-module(tcp). 

-behaviour(gen_server). 

-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, start/0, stop/0, connect/0, send/1, recv/0]). 

-export([start_link/0]). 

%% ============================================================================= 
%% EXPORTED GEN_SERVER CALLBACKS 
%% ============================================================================= 

init([]) -> {ok, {}}. 

handle_call({send, Packet}, _From, State) -> 
    gen_tcp:send(State, Packet), 
    io:format("Send Working\n"), 
    {reply, ok, State}; 

handle_call(recv, _From, State) -> 
    Message = gen_tcp:recv(State, 0), 
    io:format("~w~n", [Message]), 
    {reply, Message, State}. 

handle_cast(connect, _) -> 
    case gen_tcp:listen(6888, [binary]) of 
    {ok, LSocket}-> 
     io:format("~w~n", [LSocket]), 
     case gen_tcp:accept(LSocket) of 
     {ok, Socket} -> 
      inet:setopts(Socket, [{active, false}]), 
      io:format("accepted\n"), 
      {noreply, Socket}; 
     Other -> 
      error_logger:error_report(["An error occurred which is",Other,"in line",?LINE,"of module",?MODULE]) 

     end; 
    {error, Reason} -> 
     error_logger:error_report("An error occurred", Reason, [?LINE,?MODULE]) 
    end; 

handle_cast(stop, State) -> {stop, normal, State}. 

handle_info(_Info, State) -> {noreply, State}. 

terminate(_Reason, _State) -> ok. 

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


%% ============================================================================= 
%% EXPORTED CONVENIENCE FUNCTIONS TO START AND STOP THE SERVER 
%% ============================================================================= 

start() -> 
    case gen_server:start({local, ?MODULE}, ?MODULE, [], []) of 
     {ok, Pid} -> 
      Pid; 
     Reason -> 
      error_logger:error_report("An error occurred", Reason, [?LINE,?MODULE]) 
    end. 

stop() -> 
    case gen_server:cast(?MODULE, stop) of 
     ok -> 
      ok; 
     _ -> 
      {error, stop_error} 
    end. 


%% ============================================================================= 
%% PUBLIC API FUNCTIONS 
%% ============================================================================= 

connect() -> gen_server:cast(?MODULE, connect). 

send(Packet) -> gen_server:call(?MODULE, {send, Packet}). 

recv() -> gen_server:call(?MODULE, recv). 

write_file(Filename) -> 
    {ok, IoDevice} = file:open(test.txt, [write, append]), 
    ok. 

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


%% ============================================================================= 
%% LOCAL FUNCTIONS 
%% ============================================================================= 

我照你的建议,并实现了它作为一个handle_call但是当我跑我得到一个错误,

功能handle_call/3已经定义的错误

我相当不明白为什么我得到这个错误,因为我有3个handle_call参数,它应该工作。

handle_call(write_file, Filename, S) -> 
    {ok, File} = file:open(Filename, [append]), 
    ok = file:write(File, S), 
    ok = file:close(File). 

我的API函数

write_file() -> gen_server:call(?MODULE, write_file). 
+2

惠康的话,请放弃使用 “打着招呼” 和“感谢”并关心排版。它增加了良好答案的可能性,并有助于未来读者的问题。 –

回答

2

write_file应该这样做:

write_file(Fname, S) -> 
    ok = file:write_file(Fname, S, [append]). 

write_file(Fname, S) -> 
    {ok, File} = file:open(Fname, [append]), 
    ok = file:write(File, S), 
    ok = file:close(File). 
3

你的手柄不能正常工作,因为你有两个定义的。你写:

handle_call(...) -> 
    do_something. 

handle_call(M, F, S) -> 
    do_some_other_thing. 

你应该让他们成为一样的功能,通过改变:

do_something. 

到:

do_something; 
handle_call(M, F, S) -> 
    do_some_other_thing.