2013-03-19 4 views
0

Я создаю приложение p2p в Java для совместного использования файлов. Каждый одноранговый узел будет работать на моем компьютере на другом порту и слушать запрос. но проблема, с которой я сталкиваюсь, - это когда создается экземпляр PeerNode, мой код запускается в бесконечный цикл. Ниже приведен мой код для PeerNode. Это как я должен создать каждый узел и заставить их слушать входящие запросы?Java-одноранговое сетевое приложение - домашнее задание

После кода представляет один пэр узла:

public class PeerNode 
{ 
    private int port; 
    private ArrayList<PeerNode> contacts; 
    PeerNode preNode; 
    PeerNode postNode; 
    private String directoryLocation = ""; 

    PeerNode(int port) 
    { 
     this.port = port; 
     this.setDirectoryLocation(port+""); 
     startClientServer(port); 
    } 

    private void sendRequest(String fileName, String host, int port) throws UnknownHostException, IOException 
    { 
     Socket socket = new Socket(host, port);//machine name, port number 
     PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
     out.println(fileName); 

     out.close(); 
     socket.close(); 

    } 

    private void startClientServer(int portNum) 
    { 
     try 
     { 
      // Establish the listen socket. 
      ServerSocket server = new ServerSocket(0); 
      System.out.println("listening on port " + server.getLocalPort()); 

      while(true) 
      { 
       // Listen for a TCP connection request. 
       Socket connection = server.accept(); 

       // Construct an object to process the HTTP request message. 
       HttpRequestHandler request = new HttpRequestHandler(connection); 

       // Create a new thread to process the request. 
       Thread thread = new Thread(request); 

       // Start the thread. 
       thread.start(); 

       System.out.println("Thread started for "+ portNum); 
      } 

     } 
     catch (Exception e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 
} 

И следующий класс создает все узлы и соединяет их:

public class MasterClientServer 
{ 
    public static void main(String [] args) 
    { 
     int count = 10; 
     ArrayList<PeerNode> arrayOfNodes = createNodes(count); 
    } 

    public static ArrayList<PeerNode> createNodes(int count) 
    { 
     System.out.println("Creating a network of "+ count + " nodes..."); 
     ArrayList<PeerNode> arrayOfNodes = new ArrayList<PeerNode>(); 

     for(int i =1 ; i<=count; i++) 
     { 
      arrayOfNodes.add(new PeerNode(0)); //providing 0, will take any free node 
     } 
     return arrayOfNodes; 
    } 
} 



public class HttpRequestHandler implements Runnable 
{ 
    final static String CRLF = "\r\n"; 
    Socket socket; 

    public HttpRequestHandler(Socket socket) throws Exception 
    { 
     this.socket = socket; 
    } 

    @Override 
    public void run() 
    { 
     try 
     { 
      processRequest(); 
     } 
     catch (Exception e) 
     { 
      System.out.println(e); 
     } 

    } 

    /* 
    * Gets a request from another node. 
    * Sends the file to the node if available. 
    */ 
    private void processRequest() throws Exception 
    { 
     /*DataOutputStream os = new DataOutputStream(socket.getOutputStream()); 

     InputStream is = socket.getInputStream(); 
     BufferedReader br = new BufferedReader(new InputStreamReader(is)); 

     // Get the request line of the HTTP request message. 
     String requestLine = br.readLine(); 

     // Extract the filename from the request line. 
     // In Get request, the second token is the fie name 
     String[] tokens = requestLine.split(" "); 
     String fileName = tokens[1]; 

     // Prepend a "." so that file request is within the current directory. 
     fileName = "." + fileName; 

     // Open the requested file. 
     FileInputStream fis = null; 
     boolean fileExists = true; 

     try 
     { 
      fis = new FileInputStream(fileName); 
     } 
     catch (FileNotFoundException e) 
     { 
      fileExists = false; 
     } 

     // construct the response Message 
     // Construct the response message. 
     String statusLine = null; 
     String contentTypeLine = null; 
     String entityBody = null; 
     if (fileExists) 
     { 
      statusLine = "HTTP/1.1 200 OK" + CRLF; 
      contentTypeLine = "Content-Type: " + contentType(fileName) + CRLF; 
     } 
     else 
     { 
      statusLine = "HTTP/1.1 404 Not Found" + CRLF; 
      contentTypeLine = "Content-Type: text/html" + CRLF; 
      entityBody = "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY>Error 404: Page Not Found</BODY></HTML>"; 
     } 

     // Send the status line. 
     os.writeBytes(statusLine); 

     // Send the content type line. 
     os.writeBytes(contentTypeLine); 

     // Send a blank line to indicate the end of the header lines. 
     os.writeBytes(CRLF); 

     // Send the entity body. 
     if (fileExists) { 
      sendBytes(fis, os); 
      fis.close(); 
     } else { 
      os.writeBytes(entityBody); 
     } 
     // Close streams and socket. 
     os.close(); 
     br.close(); 
     socket.close(); 

    } 

    private static void sendBytes(FileInputStream fis, OutputStream os) 
      throws Exception 
      { 
     // Construct a 1K buffer to hold bytes on their way to the socket. 
     byte[] buffer = new byte[1024]; 
     int bytes = 0; 

     // Copy requested file into the socket's output stream. 
     while ((bytes = fis.read(buffer)) != -1) { 
      os.write(buffer, 0, bytes); 
     }*/ 
    } 

    private static String contentType(String fileName) 
    { 
     if (fileName.endsWith(".htm") || fileName.endsWith(".html")) 
     { 
      return "text/html"; 
     } 
     if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) 
     { 
      return "image/jpeg"; 
     } 
     if (fileName.endsWith(".gif")) { 
      return "image/gif"; 
     } 
     if (fileName.endsWith(".ram") || fileName.endsWith(".ra")) 
     { 
      return "audio/x-pn-realaudio"; 
     } 
     return "application/octet-stream"; 
    } 
} 
+0

Просьба подробно рассказать о бесконечном цикле. Где в коде есть цикл счетчика программ? – uldall

+0

он входит в функцию StartClientServer, и он переходит в цикл while(), он не выходит оттуда. и создается только один PeerNode. Когда я создаю PeerNode, должен ли я поставить код «прослушивать TCP-соединение» и thread.start..etc внутри цикла while, чтобы он мог слушать больше запросов? – user1998719

ответ

4

Вашего PeerNode конструктор никогда не возвращает, так как он занят приемом новых подключений. Следовательно, ваш цикл в createNodes создает только первый экземпляр PeerNode. Вы можете решить это, позвонив startClientServer в новый поток:

new Thread(new Runnable() { 
    public void run() { 
     startClientServer(port); 
    } 
}.start(); 
+0

Хорошо. Поэтому я должен поместить это внутри конструктора для PeerNode? Поэтому я создаю новый поток, который запуститClientServer на порт и внутри функции startClientServer. Я снова создаю новый поток для обработки запроса. Я немного смущен. Почему я создаю потоки внутри конструктора? – user1998719

+0

Да, вы можете либо начать поток для обработки accept() внутри конструктора, либо внутри самого метода startClientServer. В вашем случае вам нужен один поток для приема новых подключений через accept() и один поток для обработки связи для каждого нового соединения. Строго говоря, вам действительно не нужен новый поток для каждого подключения, но если вы этого не сделаете, вы можете обрабатывать только одно соединение за раз. – uldall

Смежные вопросы