【发布时间】:2014-11-29 20:38:47
【问题描述】:
我遇到了一个问题。我在 Erlang/OTP 上有一个 iOS 客户端和一个 tcp 服务器。客户端假设通过 GCDAsynchSocket 向服务器发送和接收消息。如果我需要发送消息,它工作得很好,但它不作为接受者,因为客户端必须调用这个委托方法:
/**
* Called when a socket has completed reading the requested data into memory.
* Not called if there is an error.
**/
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
问题是服务器关闭了连接,它调用了另一个委托方法(
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err;
)。
如何在客户端完成从服务器读取数据以及如何在服务器上留下工作连接,直到客户端自行断开连接? iOS 客户端从服务器获取字节,但无法正常关闭连接。
Erlang 服务器的一部分:
-behaviour (gen_server).
-export ([start_link/0, check_data/1]).
%%gen_server callbacks
-export ([init/1, handle_call/3,
handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-define (PORT, 1477).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [?PORT], []).
init([Port]) ->
process_flag(trap_exit, true),
{ok, Listen} = gen_tcp:listen(Port,
[{active, false},
binary,
{reuseaddr, true}]),
spawn(fun() ->
accept_parallel(Listen) end),
io:format("~p started~n", [?MODULE]),
{ok, 0}.
accept_parallel(Listen) ->
{ok, Socket} = gen_tcp:accept(Listen),
spawn(fun() -> accept_parallel(Listen) end),
loop(Socket).
handle_call(Request, _From, N) ->
{reply, Request, N + 1}.
handle_cast(_Msg, N) ->
{noreply, N}.
handle_info(_Info, N) ->
{noreply, N}.
terminate(_Reason, _N) ->
io:format("~p stoped~n", [?MODULE]),
ok.
code_change(_OldVsn, N, _Extra) -> {ok, N}.
loop(Socket) ->
case gen_tcp:recv(Socket, 0) of
{ok, Bin} ->
case check_data(Bin) of
ok ->
gen_tcp:send(Socket, "ok");
{error, _Data} ->
gen_tcp:send(Socket, "error")
end;
{error, Reason} ->
exit(Reason)
end.
我可以在向客户端发送消息后设置超时,但无论如何我怎样才能完成接受数据呢?
更新:我只需连接一次即可通过向客户端发送令牌来证明授权。
【问题讨论】:
标签: ios objective-c tcp erlang gcdasyncsocket