Pregunta

I modified this server to use gen_tcp:recv inorder to limit the number of bytes for a packet to 50. I commented out the line inet:setopts(Socket, [{active, once}]), because gen_tcp:recv is supposed to be {active,false}. This is the client side erl shell

2> cp3:client().
exit
3> 

and this is the server side erl shell

4> cp3:server().
Started Server:
<0.46.0>
Accept Server:
Pid <0.48.0>
Connection accepted 
Accept Server:
Loop Server:
5> 

I also wondered how can I know if the socket closed with the return value {tcp_closed, Socket} if gen_tcp:recv doesn't create one?

-module(cp3).
-export([client/0, server/0,start/0,accept/1,enter_loop/1,loop/1]).

client() ->
    {ok, Socket} =  gen_tcp:connect("localhost", 4001,[list, {packet, 0}]),
    ok = gen_tcp:send(Socket, "packet"),
    receive
        {tcp,Socket,String} ->
            io:format("Client received = ~p~n",[String]),       
            io:format("Client result = ~p~n",[String]),
            gen_tcp:close(Socket)
        after 1000 ->
            exit        
    end.

server() -> 
    Pid = spawn(fun()-> start() end),
    Pid.

start() ->  
    io:format("Started Server:~n"),
    {ok, Socket} = gen_tcp:listen(4001, [binary, {packet, 0},{reuseaddr, true},{active, false}]),
    accept(Socket).

accept(ListenSocket) ->
    io:format("Accept Server:~n"),
    case gen_tcp:accept(ListenSocket) of
        {ok, Socket} ->
            Pid = spawn(fun() ->
                io:format("Connection accepted ~n", []),
                enter_loop(Socket)
            end),
            io:format("Pid ~p~n",[Pid]),
            gen_tcp:controlling_process(Socket, Pid),
            Pid ! ack,
            accept(ListenSocket);
        Error ->
            exit(Error)
    end.

enter_loop(Socket) ->
    %% make sure to acknowledge owner rights transmission finished
    receive ack -> ok end,
    loop(Socket).

loop(Socket) ->
    %% set socket options to receive messages directly into itself
    %%inet:setopts(Socket, [{active, once}]),
    io:format("Loop Server:~n"),
    case gen_tcp:recv(Socket, 50) of
    {ok, Data} ->  
        case Data of
            <<"packet">> ->                 
                io:format("Server replying = ~p~n",[Data]),   
                gen_tcp:send(Socket, Data),
                loop(Socket)                  
        end;
    {error, Reason} ->      
        io:format("Error on socket ~p reason: ~p~n", [Socket, Reason])          
    end.
¿Fue útil?

Solución

I am not very clear about your question, but the above code does not work. Hope the following answers your problem. Your tcp receive case gen_tcp:recv(Socket, 50) of has one error. It is waiting for 50 bytes to read. Check the documentation of gen_tcp:recv/2. Change the length (length of packer 6 but preferably to) 0 to receive all the bytes.

The value does not limit the size of data, but it will not send the data back until it receives data of length 50. Instead you may need to accept and then check it.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top