/*付録3 PureP2P_Peerプログラム*/ import java.io.*; import java.net.*; import java.util.*; public class Peer { static int max_u = 0, max_d = 0,max_l = 0, max_m = 0, max_r = 0,max_s = 0, no_u = 0, no_d = 0,no_l = 0, sw = 1, max_a; static boolean child; static boolean parent; static int child_num; static int child_num2; static Member mem[]; static ListMember listmem[]; static LinkedList addressList = new LinkedList(); static LinkedList node = new LinkedList(); static LinkedList AccessList = new LinkedList(); static LinkedList Child = new LinkedList(); static int port; static String myaddress; static String dottedline = "-------------------------------------------------------------"; static String pass_up = "./file_up/"; static String pass_down = "./file_down/"; static String parent_address; static int parent_port; public static void main(String[] args) { int i1; max_u = 2; //最大同時送信数 max_d = 2; //最大同時受信数 max_l = 100; max_m = 100; max_r = 10; max_s = 10; max_a = 2; child = false; parent = false; child_num = 0; child_num2 = 0; parent_port = 0; mem = new Member [max_u]; listmem = new ListMember [max_m]; String ss; for (i1 = 0; i1 < max_u; i1++) mem[i1] = new Member(); for (i1 = 0; i1 < max_m; i1++) listmem[i1] = new ListMember(); try { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); BufferedReader fin_port = new BufferedReader(new FileReader("port.txt")); BufferedReader fin_ad = new BufferedReader(new FileReader("ad_list.txt")); System.out.println("ファイル転送用ポートの変更をしますか? yes/no"); String port_line; port_line = in.readLine(); if (port_line.equals("yes")) { PrintWriter fout_port = new PrintWriter(new BufferedWriter(new FileWriter("port.txt"))); do{ System.out.println("注:10000以上でお願いします。"); port = Integer.parseInt(in.readLine()); }while(port<10000 || 65535 0){ listmem[0].fileList.add(list[n]); } } String ss2; int ran; while (( ss = fin_ad.readLine()) != null) { if(addressList.size() > max_m-1) { ran = (int)((max_m-1)*Math.random()); node.set(ran*2,ss); ss2 = fin_ad.readLine(); node.set(ran*2+1,ss2); ss = ss + ss2; addressList.set(ran+1,ss); } else{ node.add(ss); ss2 = fin_ad.readLine(); node.add(ss2); ss = ss + ss2; addressList.add(ss); } } System.out.println("0:終了 1:検索 2:ファイルリスト出力 3:ファイル要求"); new Key().start(); new Listaccept().start(); ServerSocket f_s = new ServerSocket(port); for (;;) { Socket s = f_s.accept(); if (no_u == max_u) { System.out.println("同時送信数の限界を超えました"); s.close(); } else new Connect(s).start(); } } catch (Exception e) { System.out.println(e); } } } class Connect extends Thread { private Socket s; int n = -1; PrintWriter out; BufferedReader in; public Connect(Socket s_i) { int i1; s = s_i; Peer.no_u++; for (i1 = 0; i1 < Peer.max_u && n < 0; i1++) { if (Peer.mem[i1].state == false) { Peer.mem[i1].state = true; Peer.mem[i1].s = s; n = i1; } } try { String bt; out = new PrintWriter(s.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(s.getInputStream())); } catch (Exception e) { System.out.println(e); } } public void run() { try { String file_name; file_name = in.readLine(); String pass_up = Peer.pass_up; BufferedInputStream file_in = new BufferedInputStream(new FileInputStream(pass_up+file_name)); BufferedOutputStream file_out = new BufferedOutputStream(s.getOutputStream()); long k = 0; int bt; while ((bt = file_in.read()) >= 0) { file_out.write(bt); k++; } file_out.flush(); s.close(); Peer.no_u--; } catch (Exception e) { System.out.println(e); try { s.close(); } catch (Exception e2) { System.out.println(e); } } } } class Key extends Thread { public void run() { int i1; String line; String file_name=null; String s_list; String dottedline = Peer.dottedline; long k = 0; int bt; LinkedList fileList = new LinkedList(); LinkedList fileList2 = new LinkedList(); LinkedList s_fileList = new LinkedList(); LinkedList s_fileList2 = new LinkedList(); LinkedList node = Peer.node; Iterator s_fileList_itr; Iterator node_itr; int list_num = -1; for (i1 = 0; i1 < Peer.max_m && list_num < 0; i1++) { if (Peer.listmem[i1].state == false) { Peer.listmem[i1].state = true; list_num = i1; } } try { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); for (;;) { System.out.println("*****************************************"); System.out.println("*************入力待ち********************"); line = in.readLine(); /*s_fileListの更新*/ s_fileList.clear(); for(int s=1; s"); System.out.println("*****************************************"); System.exit(1); } else if (line.equals("1")) { if (Peer.parent==true) break if_break1; System.out.println("<検索>"); Peer.Child.clear(); Peer.AccessList.clear(); Access dt = new Access(); dt.run(); if(Peer.child_num>0){ Peer.child = true; Peer.parent = true; new tree0().start(); } } else if (line.equals("2")) { System.out.println("<ファイルリスト出力>"); for(int n=0; n"); if(Peer.no_d >= Peer.max_d){ System.out.println("同時受信数の限界を超えています。"); break if_break1; } String addr=null; int port=30000; Socket file_s; int n=-1,n2=0; do{ System.out.println(":ファイル名入力"); file_name = in.readLine(); if(file_name.equals("")) break if_break1; n=s_fileList.indexOf(file_name); if(n == -1){ System.out.println("入力したファイル名はリストに存在しません。"); System.out.println("注:大文字と小文字を区別してください。何も入力ぜずにEnterキーを押すとファイル要求は中止されます。"); } }while(n==-1); s_fileList2=(LinkedList)s_fileList.clone(); do{ n2=s_fileList2.lastIndexOf(dottedline); s_fileList2.remove(n2); }while(n"); System.out.println("0:終了 1:検索 2:ファイルリスト出力 3:ファイル要求"); } } } catch (IOException e) { System.out.println("Error : " + e); System.exit(1); } } } class Member { boolean state; Socket s; PrintWriter out; Member() { state = false; } } class ListMember { boolean state; Socket s; PrintWriter out; LinkedList fileList = new LinkedList(); ListMember() { state = false; } } class resolution { LinkedList s_fileList2 = new LinkedList(); String dottedline = Peer.dottedline; String ss; resolution(LinkedList s_fileList) { s_fileList2=(LinkedList)s_fileList.clone(); } public void run() { try{ String address; int port; int n_addr = 0; int f = 0; int n2 = 0; int ran; do{ s_fileList2.removeFirst(); address = (String)s_fileList2.get(0); port = Integer.parseInt((String)s_fileList2.get(1)); ss = address+port; n_addr=Peer.addressList.indexOf(ss); if(n_addr==-1){ if(Peer.addressList.size() > Peer.max_m-1) { ran = (int)((Peer.max_m-1)*Math.random()); Peer.node.set(ran*2,address); Peer.node.set(ran*2+1,""+port); Peer.addressList.set(ran+1,ss); n_addr = ran+1; } else { Peer.node.add(address); Peer.node.add(""+port); Peer.addressList.add(ss); n_addr = Peer.addressList.size()-1; } } else{ Peer.addressList.set(n_addr,ss); } n2=s_fileList2.indexOf(dottedline); if(n2 == -1){ n2 = s_fileList2.size(); f = 1; } else{ n2 = n2--;} Peer.listmem[n_addr].fileList.clear(); Peer.listmem[n_addr].fileList.add(dottedline); for(int n=0; n= 0) { file_out_f.write(bt); k++; } file_out_f.close(); Peer.no_d--; System.out.println(file_name + ":" + k + "バイト受け取りました。"); if(k==0){ System.out.println("相手の同時転送数を超えている可能性があります。"); } file_s.close(); k=0; } catch (Exception e) { Peer.no_d--; System.out.println("Reception:"+e); } } } class Listaccept extends Thread{ public void run() { try { ServerSocket l_s = new ServerSocket(Peer.port-5000); for (;;) { Socket s = l_s.accept(); if (Peer.no_l == Peer.max_l) { System.out.println("同時リスト待ち受けの限界を超えました"); System.out.println("*************入力待ち********************"); s.close(); } else{ new s_List(s).start(); } } } catch (Exception e) { System.out.println("Listaccept:"+e); } } } class s_List extends Thread { private Socket list_s; int n = -1; PrintWriter out; BufferedReader in; LinkedList s_fileList = new LinkedList(); LinkedList node = Peer.node; public s_List(Socket s) { list_s = s; try { String bt; out = new PrintWriter(s.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(s.getInputStream())); } catch (Exception e) { System.out.println("s_Listのリスト処理のスレッド:"+e); } } public void run() { int i1; int n5; int num; String line=null; String dottedline = Peer.dottedline; LinkedList fileList = new LinkedList(); LinkedList fileList2 = new LinkedList(); LinkedList s_fileList2 = new LinkedList(); LinkedList ad = new LinkedList(); LinkedList LinkAddress = new LinkedList(); Iterator ad_itr; Iterator s_fileList_itr; try { line = in.readLine(); if(line.equals("Access")){ String address,port; InetAddress addr =list_s.getInetAddress(); address = addr.getHostAddress(); port = in.readLine(); if(Peer.child == true){ out.println("NO"); } else out.println("OK"); } if(line.equals("tree")){ String address; int port; InetAddress addr =list_s.getInetAddress(); address = addr.getHostAddress(); port = Integer.parseInt(in.readLine()); if(Peer.child == false){ Peer.child = true; Peer.Child.clear(); Peer.AccessList.clear(); Access dt3 = new Access(); dt3.run(); Peer.parent_address = address; Peer.parent_port = port; if(Peer.AccessList.size() == 0){ out.println("OK"); list_s.close(); } else{ tree dt = new tree(list_s); dt.run(); } } else{ out.println("NO"); list_s.close(); } } if(line.equals("tree_list")){ if(Peer.Child.size() > 0){ new tree_list(list_s).start(); } else{ PrintWriter out = new PrintWriter(list_s.getOutputStream(), true); out.println("list_start"); for(int s=0; s 0){ new tree_list_r().start(); } Peer.child = false; Peer.parent = false; Peer.child_num = 0; Peer.child_num2 = 0; Peer.AccessList.clear(); } else; } catch (Exception e) { System.out.println("s_List"+e); Peer.listmem[n].state = false; } } } class Access{ LinkedList node =(LinkedList)Peer.node.clone(); String address; int port; int num = 0; Socket s; int ran=0; public Access() { } public void run() { try{ do{ num++; ran = (int)((node.size()/2)*Math.random()); address = (String)node.get(ran*2); port = Integer.parseInt((String)node.get(ran*2+1))-5000; node.remove(ran*2); node.remove(ran*2); try{ s = new Socket(address,port); Peer.AccessList.add(address); Peer.AccessList.add(""+port); Peer.child_num++; PrintWriter out = new PrintWriter(s.getOutputStream(), true); out.println("Access"); out.println(Peer.port); BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = in.readLine(); if(line.equals("NO")){ Peer.AccessList.remove(Peer.AccessList.size()-1); Peer.AccessList.remove(Peer.AccessList.size()-1); Peer.child_num--; num--; } } catch (Exception e) { num--; } }while(node.size() > 0 && Peer.max_a > num); } catch (Exception e) { System.out.println("Access:"+e); } } } class tree0 extends Thread{ public tree0() { } public void run() { tree dt = new tree(); dt.run(); } } class tree { String address; int port; int f = 0; String line; Socket s; Socket s2; public tree() { } public tree(Socket list_s) { s2 = list_s; f = 1; } public void run() { LinkedList AccessList =(LinkedList)Peer.AccessList.clone(); try{ do{ address = (String)AccessList.get(0); port = Integer.parseInt((String)AccessList.get(1)); AccessList.remove(0); AccessList.remove(0); try{ s = new Socket(address,port); if(f == 0){ new tree2(s,address,port).start(); } else { new tree2(s,address,port,s2).start(); } } catch (Exception e) { } }while(AccessList.size() > 0); } catch (Exception e) { System.out.println("tree:"+e); } } } class tree2 extends Thread{ String address; int port; String line; Socket s; Socket s2; int f = 0; public tree2(Socket s3, String address2, int port2) { s = s3; address = address2; port = port2; } public tree2(Socket s3, String address2, int port2, Socket s4) { s = s3; address = address2; port = port2; s2 = s4; f = 1; } public void run() { try{ PrintWriter out2 = new PrintWriter(s.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); out2.println("tree"); out2.println(Peer.port); line = in.readLine(); if(line.equals("OK")){ Peer.child_num2++; Peer.Child.add(address); Peer.Child.add(""+port); } else if(line.equals("NO")){ Peer.child_num2++; } else { System.out.println("エラー"); } if(Peer.child_num == Peer.child_num2){ if(f == 1){ PrintWriter out = new PrintWriter(s2.getOutputStream(), true); out.println("OK"); s.close(); s2.close(); } if(Peer.parent == true && Peer.Child.size()>0 ){ new tree_list().start(); } } } catch (Exception e) { System.out.println("tree2:"+e); } } } class tree_list extends Thread{ LinkedList Child_clone = (LinkedList)Peer.Child.clone(); String address; int port; Socket s,s2; int child_num = 0; LinkedList fileList = new LinkedList(); String line; public tree_list() { } public tree_list(Socket s_list) { s2 = s_list; } public void run() { try{ do{ address = (String)Child_clone.get(0); port = Integer.parseInt((String)Child_clone.get(1)); Child_clone.remove(0); Child_clone.remove(0); try{ s = new Socket(address,port); child_num++; PrintWriter out = new PrintWriter(s.getOutputStream(), true); out.println("tree_list"); BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); for(;;){ line = in.readLine(); if(line.equals("list_end")) break; fileList.add(line); if(line.equals("list_start")) fileList.clear(); } resolution dt = new resolution(fileList); dt.run(); if(Peer.Child.size()/2 == child_num && Peer.parent == false){ PrintWriter out2 = new PrintWriter(s2.getOutputStream(), true); out2.println("list_start"); for(int s=0; s 0); } catch (Exception e) { } } } class tree_list_r extends Thread{ LinkedList Child_clone = (LinkedList)Peer.Child.clone(); String address; int port; Socket s; int child_num = 0; LinkedList fileList = new LinkedList(); String line; public tree_list_r() { } public void run() { try{ do{ address = (String)Child_clone.get(0); port = Integer.parseInt((String)Child_clone.get(1)); Child_clone.remove(0); Child_clone.remove(0); try{ s = new Socket(address,port); child_num++; PrintWriter out = new PrintWriter(s.getOutputStream(), true); out.println("tree_list_r"); out.println("list_start"); for(int s=0; s 0); Peer.child = false; Peer.parent = false; Peer.child_num = 0; Peer.child_num2 = 0; Peer.AccessList.clear(); } catch (Exception e) { } } }