/carrier/dataServer/client.erl

http://egfs.googlecode.com/ · Erlang · 204 lines · 181 code · 18 blank · 5 comment · 4 complexity · a24e49b78e9fd36acf6e787e20e05f1d MD5 · raw file

  1. -module(client).
  2. -include("../include/egfs.hrl").
  3. -import(toolkit).
  4. -export([write/0, read/0]).
  5. -define(STRIP_SIZE, 8192).
  6. -define(CHKID, <<0,0,172,10,0,9,103,237>>).
  7. -define(Node, {data_server, lt@lt}).
  8. -define(NextNode, {data_server, ltlt@lt}).
  9. -define(SIZE, 1073741824). %% 2684354560
  10. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  11. %% write & read tester
  12. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  13. write() ->
  14. FileID = 2000,
  15. ChunkIndex = 0,
  16. Nodelist = [?Node, ?NextNode],
  17. [H|T] = Nodelist,
  18. Reply = gen_server:call(H, {writechunk, FileID, ChunkIndex, ?CHKID, T}),
  19. io:format("[~p, ~p] Reply ~p~n", [?MODULE, ?LINE, Reply]),
  20. {ok, Host, Port} = Reply,
  21. Result = send_control(Host, Port),
  22. io:format("[~p, ~p] Result ~p~n", [?MODULE, ?LINE, Result]).
  23. read() ->
  24. Reply = gen_server:call(?Node, {readchunk, ?CHKID, 0, ?SIZE}),
  25. io:format("Reply ~p~n", [Reply]),
  26. {ok, Host, Port} = Reply,
  27. Result = receive_control(Host, Port),
  28. io:format("Result ~p~n", [Result]).
  29. %% send data to data server
  30. send_control(Host, Port) ->
  31. {ok, Socket} = gen_tcp:connect(Host, Port, [binary, {packet, 2}, {active, true}]),
  32. process_flag(trap_exit, true),
  33. receive
  34. {tcp, Socket, Binary} ->
  35. {ok, Data_Port} = binary_to_term(Binary),
  36. Parent = self(),
  37. Child = spawn_link(fun() -> send_data(Host, Data_Port, Parent) end),
  38. Result = transfer_control(Socket, Child);
  39. {tcp_closed, Socket} ->
  40. Result = {error, control_connect, "control connect broken when waitin for data port"}
  41. end,
  42. gen_tcp:close(Socket),
  43. Result.
  44. transfer_control(Socket, Child) ->
  45. receive
  46. {finish, Child, Len} ->
  47. Child ! {die, self()},
  48. wait_for_check(Socket, Len);
  49. {tcp, Socket, Binary} ->
  50. Term = binary_to_term(Binary),
  51. case Term of
  52. {error, Why} ->
  53. {error, control_connect, Why};
  54. _Any ->
  55. transfer_control(Socket, Child)
  56. end;
  57. {tcp_closed, Socket} ->
  58. {error, control_connect, "control connect broken"}
  59. end.
  60. wait_for_check(Socket, Len) ->
  61. receive
  62. {tcp, Socket, Binary} ->
  63. Term = binary_to_term(Binary),
  64. case Term of
  65. {check, Len} ->
  66. Result = {ok, check},
  67. gen_tcp:send(Socket, term_to_binary(Result)),
  68. {ok, check, Len};
  69. _Other ->
  70. Result = {error, check, "length error"},
  71. gen_tcp:send(Socket, term_to_binary(Result)),
  72. Result
  73. end;
  74. {tcp_closed, Socket} ->
  75. {error, check, "broken socket"};
  76. _Any ->
  77. wait_for_check(Socket, Len)
  78. end.
  79. send_data(Host, Port, Parent) ->
  80. {ok, Hdl} = file:open("hello_1.mp3", [binary, raw, read]),
  81. {ok, FileSize} = toolkit:get_file_size("hello_1.mp3"),
  82. {ok, DataSocket} = gen_tcp:connect(Host, Port, [binary, {packet, 2}, {active, true}]),
  83. io:format("Transfer begin: ~p~n", [erlang:time()]),
  84. loop_send(Parent, DataSocket, Hdl, 0, FileSize, 0),
  85. gen_tcp:close(DataSocket),
  86. io:format("Transfer end: ~p~n", [erlang:time()]).
  87. loop_send(Parent, DataSocket, Hdl, Begin, End, Len) when Begin < End ->
  88. {ok, Binary} = file:pread(Hdl, Begin, ?STRIP_SIZE),
  89. gen_tcp:send(DataSocket, Binary),
  90. Size = size(Binary),
  91. Len2 = Len + Size,
  92. Begin2 = Begin + Size,
  93. loop_send(Parent, DataSocket, Hdl, Begin2, End, Len2);
  94. loop_send(Parent, DataSocket, _, _, _, Len) ->
  95. Parent ! {finish, self(), Len},
  96. wait_to_die(Parent, DataSocket).
  97. wait_to_die(Parent, DataSocket) ->
  98. receive
  99. {die, Parent} ->
  100. gen_tcp:close(DataSocket),
  101. {ok, die};
  102. _Any ->
  103. wait_to_die(Parent, DataSocket)
  104. end.
  105. %% receive data from data server
  106. receive_control(Host, Port) ->
  107. {ok, Socket} = gen_tcp:connect(Host, Port, [binary, {packet, 2}, {active, true}]),
  108. process_flag(trap_exit, true),
  109. receive
  110. {tcp, Socket, Binary} ->
  111. {ok, Data_Port} = binary_to_term(Binary),
  112. Parent = self(),
  113. Child = spawn_link(fun() -> receive_data(Host, Data_Port, Parent) end),
  114. Result = transfer_control_read(Socket, Child);
  115. {tcp_closed, Socket} ->
  116. Result = {error, control_connect, "control connect broken when waitin for data port"}
  117. end,
  118. Result.
  119. transfer_control_read(Socket, Child) ->
  120. receive
  121. {finish, Child, Len} ->
  122. ?DEBUG("[~p, ~p]:read a chunk, size is ~p.~n",[?MODULE, ?LINE, Len]),
  123. gen_tcp:send(Socket, term_to_binary({check, data_length})),
  124. wait_for_check_result(Socket, Len);
  125. {error, Child, Why} ->
  126. ?DEBUG("[~p, ~p]:data receive socket error!~p~n",[?MODULE, ?LINE, Why]),
  127. {error, read_data, Why};
  128. {tcp, Socket, Binary} ->
  129. Term = binary_to_term(Binary),
  130. case Term of
  131. {stop, Why} ->
  132. ?DEBUG("[~p, ~p]:stop ctrl message from dataserver~n",[?MODULE, ?LINE]),
  133. Child ! {stop, self(), Why},
  134. {error, stop, "receive stop from data server"};
  135. _Other ->
  136. ?DEBUG("[~p, ~p]:unknow msg from control socket:~p~n",[?MODULE, ?LINE, Term]),
  137. transfer_control_read(Socket, Child)
  138. end;
  139. {tcp_closed, Socket} ->
  140. ?DEBUG("[~p, ~p]: read control socket broken~n",[?MODULE, ?LINE]),
  141. {error, control_connect, "read control socket broken"};
  142. Any ->
  143. ?DEBUG("[~p, ~p]:unknow messege!:~p~n",[?MODULE, ?LINE, Any]),
  144. transfer_control_read(Socket, Child)
  145. end.
  146. wait_for_check_result(Socket, Len) ->
  147. receive
  148. {tcp, Socket, Binary} ->
  149. Term = binary_to_term(Binary),
  150. case Term of
  151. {check, Len} ->
  152. {ok, Len};
  153. {check, _Other} ->
  154. {error, check_len_error, "data received length check error"};
  155. _Any ->
  156. wait_for_check_result(Socket, Len)
  157. end;
  158. {tcp_closed, Socket} ->
  159. ?DEBUG("[~p, ~p] control socket broken when waiting for check result~n", [?MODULE, ?LINE]),
  160. {error, control_socket, "Control socket broken waiting for check result"};
  161. _AnyOther ->
  162. wait_for_check_result(Socket, Len)
  163. end.
  164. receive_data(Host, Port, Parent) ->
  165. io:format("data port:~p~n", [Port]),
  166. {ok, Hdl} = file:open("recv.dat", [raw, append, binary]),
  167. {ok, DataSocket} = gen_tcp:connect(Host, Port, [binary, {packet, 2}, {active, true}]),
  168. io:format("Transfer begin: ~p~n", [erlang:time()]),
  169. loop_receive(Parent, DataSocket, Hdl, 0),
  170. gen_tcp:close(DataSocket),
  171. file:close(Hdl),
  172. io:format("Transfer end: ~p~n", [erlang:time()]).
  173. loop_receive(Parent, DataSocket, Hdl, Len) ->
  174. receive
  175. {tcp, DataSocket, Data} ->
  176. write(Data, Hdl),
  177. Len2 = Len + size(Data),
  178. loop_receive(Parent, DataSocket, Hdl, Len2);
  179. {tcp_closed, DataSocket} ->
  180. Parent ! {finish, self(), Len},
  181. io:format("read chunk over!~n");
  182. {stop, Parent, _Why} ->
  183. gen_tcp:close(DataSocket)
  184. end.
  185. write(Data, Hdl) ->
  186. file:write(Hdl, Data).