2017-01-11 25 views
0

Моя проблема заключается в том, что в моем клиенте dis.read() возвращает -1, заставляя его фактически не получать файл. Единственное, о чем я могу думать, это то, что, поскольку я использую PrintWriter и BufferedReader перед этим разделом, dis.read() считает, что все данные уже получены.Клиентский сокет не получит данные с сервера

Client Код:

public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException { 
    Socket client = new Socket(serverAddress, port); 
    client.setSoTimeout(5000); 
    PrintWriter out = new PrintWriter(client.getOutputStream(), true); 
    BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream())); 

    try { 
     out.println("101|" + fileName + "\n"); 

     if (input.readLine().equals("201")) { 
      int br; 
      byte[] data = new byte[4096]; 

      DataInputStream dis = new DataInputStream(client.getInputStream()); 
      FileOutputStream fos = new FileOutputStream(fileOut); 

      while ((br = dis.read(data, 0, data.length)) != -1){ 
       fos.write(data, 0, br); 
      } 

      fos.close(); 
      dis.close(); 
     } 
    } catch (SocketTimeoutException ste) { 
     ste.printStackTrace(); 
     client.close(); 
    } 
} 

сервера Код:

private void sendFile(String filename, Socket client) throws IOException { 
    int br; 
    byte[] data = new byte[4096]; 
    PrintWriter out = new PrintWriter(client.getOutputStream(), true); 

    out.println("201\n"); 

    DataOutputStream dos = new DataOutputStream(client.getOutputStream()); 
    FileInputStream fis = new FileInputStream(MeshFS.properties.getProperty("repository") + filename); 

    while ((br = fis.read(data, 0, data.length)) != -1) { 
     dos.write(data, 0, br); 
     dos.flush(); 
    } 

    fis.close(); 
    dos.close(); 
} 

private String receiveRequest(Socket client) { 
    String requestPart; 
    String requestFull = ""; 
    try { 
     BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream())); 

     while (((requestPart = input.readLine()) != null) && (requestFull.length() < 2048)) { 
      if (requestPart.equals("")) break; 
      requestFull = requestFull + requestPart; 
     } 

     return requestFull; 
    } catch (IOException ioe) { 
     return requestFull; 
    } 
} 

private void processRequest(String request, Socket out) { 

    if (request != null) { 
     try { 
      String[] requestParts = request.split("\\|"); 
      if (requestParts[0].equals("101")) {   //101:Get file 
       sendFile(requestParts[1], out); 

      } else { 
       badRequest(out, request); 
      } 
     } catch (Exception e) { 
      badRequest(out, request); 
      e.printStackTrace(); 
     } 
    } 
} 

    public void run() { 
     while (!Thread.interrupted()) { 
      try { 
       server.setSoTimeout(1000); 
       Socket client = server.accept(); 
       client.setSoTimeout(timeout); 
       processRequest(receiveRequest(client), client); 
       client.close(); 
      } catch (SocketTimeoutException ste) { 
      } catch (IOException io) { 
       io.printStackTrace(); 
      } 
     } 
     System.out.println("Socket closed"); 
} 

Есть ли что-то, что я пропускаю или забыть включить? Разве я ничего не смываю или что-то не очищаю?

+0

Вы могли бы предоставить больше кода? я хотел бы видеть ту часть, где вы принимаете соединение с сервером –

+0

Я обновил свой код, чтобы включить в него почти все, посмотрите пожалуйста. –

ответ

1

Хорошо, я догадываюсь, что нашел ошибку. Я сделал несколько экспериментов и выяснил, что InputStream ведет себя странно, если несколько объектов пытаются их прочитать. В вашем случае это, скорее всего, BufferedReader и DataInputStream в методе вашего клиента receiveFile, вызывающем проблему, пытаясь прочитать с того же inputStream. Я предлагаю использовать DataInputStream, чтобы также прочитать первую строку, поэтому вам не нужно создавать BufferedReader. Несмотря на то, что метод DataInputStream.readLine() устарел, он все равно будет хорошо работать в вашем случае.

Я редактировал метод receiveFile, чтобы использовать DataInputStream для чтения первой строки. Надеюсь, что это работает!

public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException { 
    Socket client = new Socket(serverAddress, port); 
    client.setSoTimeout(5000); 
    PrintWriter out = new PrintWriter(client.getOutputStream(), true); 
    DataInputStream dis = new DataInputStream(client.getInputStream()); 

    try { 
     out.println("101|" + fileName + "\n"); 

     if (dis.readLine().equals("201")) { 
      int br; 
      byte[] data = new byte[4096]; 

      FileOutputStream fos = new FileOutputStream(fileOut); 

      while ((br = dis.read(data, 0, data.length)) != -1){ 
       fos.write(data, 0, br); 
      } 

      fos.close(); 
      dis.close(); 
     } 
    } catch (SocketTimeoutException ste) { 
     ste.printStackTrace(); 
     client.close(); 
    } 
}