2016-04-08 34 views
0

gen_tcp davranış kullanırken ilginç bir sorun buldum. Bir sunucum ve bir müşterim var. Sunucu bağlantıları kabul eder ve istemci, dinleme sunucusuna bağlanmaya çalışan birçok işlem oluşturur.gen_tcp kullanırken soketlerin kabul oranı

Aynı anda birden çok yuvaya bağlanmayı deneyen birçok işlemi başlatan istemciyi başlatmaya çalışırsam çok başarısız olur. Ancak timer:sleep(x)'u koyarsam, her soket kabul ediliyor.

Bu, gen_tcp:accept()'un bağlantı isteğini kabul edebileceği bir limite sahip olduğu anlamına mı geliyor? sunucu ve istemci için

Kod aşağıdaki gibidir:

accept(State = #state{lsocket = LSocket, num = Num}) -> 
    case gen_tcp:accept(LSocket) of 
    {ok, Socket} -> 
     io:format("Accepted ~p ~n", [Num]), 
     {sockets, List} = hd(ets:lookup(csockets, sockets)), 
     NewList = [Socket | List], 
     ets:insert(csockets, {sockets, NewList}), 
     Pid = spawn(fun() -> loop(Socket) end), 
     gen_tcp:controlling_process(Socket, Pid), 
     accept(State#state{num = Num + 1}); 
    {error, closed} -> State 
    end. 

loop(Socket) -> 
    case gen_tcp:recv(Socket, 0) of 
    {ok, Data} -> 
     gen_tcp:send(Socket, Data), 
     loop(Socket); 
    {error, closed} -> 
     io:format(" CLOSED ~n"), 
     ok 
    end. 

Müşteri:

send(State = #state{low = Low, high = Low}) -> 
    State; 
send(State = #state{low = Low}) -> 
    N = Low rem 10, 
    Dest = lists:nth(N + 1, State#state.dest), 
    spawn(?MODULE, loop, [Dest, Low]), 
    %%timer:sleep(1), 
    NewState = State#state{low = Low + 1}, 
    send(NewState). 

loop({IP, Port}, Low) -> 
    case gen_tcp:connect(IP, Port, [binary]) of 
    {ok, Socket} -> 
     io:format("~p Connected ~n", [Low]), 
     gen_tcp:send(Socket, "Hi"), 
     receive 
     {tcp, RecPort, Data} -> 
      io:format("I have received ~p on port ~p ~p ~n", [Data, RecPort, Low]) 
     end; 
    _Else -> 
     io:format("The connection failed ~n"), 
     loop({IP, Port}, Low) 
    end. 
+3

Sunucuya bağlanama nedenini öğrenmek için istemcide _Else sonucunu yazdırabilirsiniz. Gönderinizi daha kolay okumak için yeniden biçimlendirdim. İstemcinin bağlanmayı başarması durumunda, istemcinin kapanmayacağı ve işlemin hemen sona ereceği ve soketin kapatıldığı anlaşılmaktadır. – Pascal

+2

Varsayılan olarak 5 olduğu gibi, TCP dinleme iş listenizi kontrol etmeniz gerekir. Dinleme çağrınızda, 'B' bir tamsayı olan' {backlog, B} 'seçeneği ile ayarlayabilirsiniz. Oh, ve ayrıca, 'gen_tcp' bir davranış değil, sadece bir modül. –

cevap

1

Bu doğru olduğunu bir tek işlem yapabilirsiniz sadece gen_tcp:accept/1 Bunun olduğundan emin değilim gerçi, o kadar hızlı koştuğunuz darboğaz.

Ranch, Cowboy web sunucusu için TCP kitaplığı ile ilgilenebilirsiniz. Kılavuzda, birçok alıcıyı kullanmaktan söz eden bir section on internal features bulunmaktadır.

Sizin durumunuzda, kendiniz için daha fazla hata ayıklama çıktısı üretmeye çalışmalısınız. İstemci bağlanamadığında hatayı yazdırmak iyi bir başlangıç ​​olabilir - bir TCP istemcisinin bağlanamaması için birçok neden vardır.