Commits

wjzz committed 9576983 Draft

Generalized some code to allow UDP in the future.

  • Participants
  • Parent commits 8435574

Comments (0)

Files changed (8)

+0. rethink again the state transitions for the peer in peer.erl - it's badly written
+1. send 'keep-alive' msgs every 2 seconds
+2. enable listening for new connections
+3. do something when the hash-test becomes false
+4. keep stats so we can see which seeders are 'fast'

File Erlang/logging.erl

 %% @end
 %%--------------------------------------------------------------------
 
+router({"peers_completion", _Params}) ->
+    peer_stats ! {peer_short_report, self()},
+    Response = receive 
+                   {peer_report, R} -> R
+               end,       
+    {ok, Response};
 
 router({"piece_completion", _Params}) ->
     {{pieces_num, PiecesNum},
 %%     Response = lists:append([ io_lib:format("~p~n", [Msg]) || Msg <- MsgList ]),
 %%     {ok, Response};
 
-%% router({"peers_completion", _Params}) ->
-%%     peer_stats ! {peer_short_report, self()},
-%%     Response = receive 
-%%                    {peer_report, R} -> R
-%%                end,       
-%%     {ok, Response};
 
 %% router({"peers", _Params}) ->
 %%     %% Ask the event_logger for a report
 %%                      TrackerInfo),
 %%     {ok, lists:append(Msgs)};
 
-router({URL, Params}) ->
+router({_URL, _Params}) ->
     serve_file.

File Erlang/metadata.erl

 
 %% single file example
 ex() ->
-%%    {ok, Content} = file:read_file("data/keizoku.torrent"),
-    {ok, Content} = file:read_file("data/immortal.torrent"),
+    {ok, Content} = file:read_file("data/chopin2.torrent"),
+%%    {ok, Content} = file:read_file("data/immortal.torrent"),
     Content.
 
 %% multifile example
 ex2() ->
-    {ok, Content} = file:read_file("data/folder.torrent"),
+    {ok, Content} = file:read_file("data/geb.torrent"),
+    %% {ok, Content} = file:read_file("data/chopin.torrent"),
+%%    {ok, Content} = file:read_file("data/immortal.torrent"),
+%%    {ok, Content} = file:read_file("data/folder.torrent"),
     Content.
 
 
     get_http_servers(RawServers, []).
 
 get_http_servers([], Acc) ->
-    lists:reverse(Acc);
+    Acc;
 
 get_http_servers([Raw|Rest], Acc) ->
     [Protocol, Host | _MaybeUri] = string:tokens(Raw, "/"),
-    case Protocol of
-        "udp:" ->
-            get_http_servers(Rest, Acc);
-        "http:" ->
-            Pair = case string:tokens(Host, ":") of
-                       [Server] -> 
-                           {Server, 80};
-                       [Server, PortNoStr] -> 
-                           {Server, atoi(PortNoStr)}
-                   end, 
-            get_http_servers(Rest, [Pair|Acc])           
-    end.
+    Tracker = case string:tokens(Host, ":") of
+                  [Server] -> 
+                      {Server, 80};
+                  [Server, PortNoStr] -> 
+                      {Server, atoi(PortNoStr)}
+              end, 
+
+    Pair = case Protocol of
+               "udp:" ->
+                   {udp, Tracker};
+               "http:" ->
+                   {tcp, Tracker}
+           end,
+    get_http_servers(Rest, [Pair|Acc]).
 
 %%===========%%
 %%  Helpers  %%

File Erlang/peer.erl

           end,
 
     log({peer, {Peer, {status, Status}}}),
-    io:format("~p~n", [Status]),
+    %% io:format("~p~n", [Status]),                
     peer_update_status(PeerPid, Status),
 
     communicate(Peer, PeerPid, Socket, MetaInfo);
             pieces:downloaded_block({Peer, PeerPid}, 
                                     {Index, Offset, Content}),
             
-            {Host,_} = Peer,
-            log({peer, {Peer, {received, Index, Offset}}}),
-            1
+            %% {Host,_} = Peer,                    
+            log({peer, {Peer, {received, Index, Offset}}})
+            %% 1                                   
 
             %% io:format("Received a part from ~s: ~p/~p of size ~p~n~n",
             %%           [pretty_ip(Host), Index, Offset,
 %% handle incoming mesages
 
 handle_msg({add_to_request_queue, PieceNo}, State) ->
-    to_be_scheduled = State#state.my_status,
-    io:format("Got scheduled #~p; [~p]~n",
-              [PieceNo, State#state.peer]),
+    %%to_be_scheduled = State#state.my_status,
+
+    %% io:format("Got scheduled #~p; [~p]~n",
+    %%           [PieceNo, State#state.peer]),
 
     RequestQueue = State#state.request_queue,
     NewQueue = [PieceNo|RequestQueue],
                 my_status = scheduled
                };
 
-handle_msg({piece_completed, _PieceNo}, State) ->
-    waiting = State#state.my_status,
+handle_msg({piece_completed, PieceNo}, State) ->
+    {Host, _} = State#state.peer,
+    io:format("Peer ~p finished #~p~n",
+              [pretty_ip(Host), PieceNo]),
+
+    %%waiting = State#state.my_status,
     
-    State#state{my_status = idle,
-                requested_pieces = [] % Better: remove PieceNo from Waiting
-               };
+    State;
+    %% State#state{my_status = idle,
+    %%             requested_pieces = [] % Better: remove PieceNo from Waiting
+    %%            };
 
 handle_msg({pieces_available, Sender}, State) ->
     Available = State#state.available_pieces,
             [PartNo|RemainingRequests] = RequestQueue,
             Request = build_whole_part_request(PieceSize, PartNo),
             ok = gen_tcp:send(Socket, Request), 
-            io:format("Send request to ~p for #~p~n", [Peer, PartNo]),
+
+            {Host,_} = Peer,
+            io:format("Request #~p from ~p~n", [PartNo, pretty_ip(Host)]),
                       
             State#state{ request_queue = RemainingRequests,
                          requested_pieces = [PartNo | Waiting],
 analyze_bitvector(BitVector, Parts) ->
     analyze_bitvector(BitVector, Parts, 0, []).
 
-analyze_bitvector(_BitVector, 0, Current, Acc) -> 
-    Percentage = (100*length(Acc))/Current,
-    io:format("Found ~.2f% || ~p/~p completed.~n", 
-              [Percentage, length(Acc),Current]),
+analyze_bitvector(_BitVector, 0, _Current, Acc) -> 
+    %% Percentage = (100*length(Acc))/Current,
+    %% io:format("Found ~.2f% || ~p/~p completed.~n", 
+    %%           [Percentage, length(Acc),Current]),
     Acc;
 
 analyze_bitvector(<<A:1, Rest/bitstring>>, Remaining, Current, Acc) ->

File Erlang/peer_stats.erl

                     {new_peer, Peer} ->
                         Value = {choked, uninterested, sets:new()},
                         NewPeerInfoDict = dict:store(Peer,Value,PeerInfoDict),
-                        io:format("Added ~p~n", [Peer]),
+                        %%io:format("Added ~p~n", [Peer]),
                         {[Peer|Peers], NewPeerInfoDict, PieceDict};
 
                     {peer_initial_have, Peer, BitStringHave} ->

File Erlang/torrent.erl

 start() ->
     catch(unregister(worker)),
     catch(unregister(listener)),
-    download_torrent(metadata:single()).
+    download_torrent(metadata:multi()).
 
 %%======================================================%%
 %%  Top-level functions that starts the whole business  %%

File Erlang/tracker.erl

 %% Tries to connect to Host and sends the Request,
 %% while displaying any error that happens during the connection.
 
-connect_trap(Request, {Host, PortNo}) ->
+connect_trap(Request, {Protocol, {Host, PortNo}}) ->
     %%io:format("Trying: ~s~n", [Host]),
     try 
-        connect(Request, Host, PortNo)
+        connect(Protocol, Request, Host, PortNo)
     catch
         Type:Error -> 
             log({tracker, Host, error}),
 %%  Connecting to the tracker  %%
 %%=============================%%
 
-connect(Request, Host, PortNo) ->    
+connect(tcp, Request, Host, PortNo) ->    
     {ok, Socket} = gen_tcp:connect(Host, PortNo, [binary, {packet, 0}]),
     ok           = gen_tcp:send(Socket, Request),
     Response     = binary_to_list(receive_data(Socket, [])),
     gen_tcp:close(Socket),
-    extract_response(Host, Response).
+    extract_response(Host, Response);
+
+connect(udp, _Request, _Host, _PortNo) ->
+    io:format("UDP not supported.~n").
+    %% {ok, Socket} = gen_udp:open(0, [binary]),
+    %% ok = gen_udp:send(Socket, Host, PortNo, Request),
+    %% Reply = receive
+    %%             {udp, Socket, _, _, Bin} ->
+    %%                 {ok, Bin}
+    %%         after 12000 ->
+    %%                 error
+    %%         end,
+    %% case Reply of
+    %%     error ->
+    %%         io:format("UDP Connection timed out: ~s:~p.~n", 
+    %%                   [helpers:pretty_ip(Host), PortNo]);
+
+    %%     {ok, Response} ->
+    %%         gen_udp:close(Socket),
+    %%         extract_response(Host, binary_to_list(Response))
+    %% end.
               
 %%=====================================%%
 %%  Some hardcoded trackers for tests  %%
 %%===========================%%
 
 extract_response(Host, Response) ->
+    %%io:format("Response from ~s: ~p~n", [helpers:pretty_ip(Host), Response]),
     {Header, Msg} = break(Response, "\r\n\r\n"),
     Headers = lines(Header),
 

File Erlang/www/monitor.js

 }
 
 function interval_function(){
+    get_peers_completion();
     get_piece_info();
 }