2014-04-20 200 views
1

我正在寫我的第一個Java客戶端/服務器程序,它只是建立一個連接。客戶端發送一個句子(文件名),服務器將文件發送給客戶端。異常:java.io.UTFDataFormatException:服務器/客戶端

但是,當我試圖讀取文件的名稱,我得到這個異常:java.io.UTFDataFormatException: malformed input around byte 65

客戶:

import java.io.*; 
import java.net.*; 
public class cliente2 { 
    public static void main(String[] args) { 
     Socket yo = null; 
     PrintWriter alServidor; 
     BufferedReader delTeclado; 
     DataInputStream delServidor; 
     String tecleado; 
     try { 
      try { 
       InetAddress direccion = InetAddress.getByName("127.0.0.1"); 
       yo = new Socket(direccion, 400); 
      } catch (UnknownHostException e) { 
       System.out.println(e.getMessage()); 
       System.exit(1); 
      } 
      System.out.println("El cliente se conecto satisfactoriamente"); 
      delTeclado = new BufferedReader(new InputStreamReader(System.in)); 
      alServidor = new PrintWriter(yo.getOutputStream(), true); 
      // Creamos flujo de entrada para leer los datos que envia el cliente 
      delServidor = new DataInputStream(yo.getInputStream()); 
      System.out.print("Por favor digite el archivo que desea descargar "); 
      tecleado = delTeclado.readLine(); 
      alServidor.println(tecleado); 
      // System.out.println("Recibiendo el archivo1"); 
      // yo.setSoTimeout(2000); 
      // yo.setKeepAlive(true); 
      //delTeclado.close(); 
      //alServidor.close(); 
      // Obtenemos el nombre del archivo 
      String nombreArchivo = dis.readUTF().toString(); 
      System.out.println("Recibiendo el archivoser : " + nombreArchivo); 
      // Obtenemos el tamano del archivo 
      int tam = delServidor.readInt(); 
      System.out.println("Recibiendo el archivostam : " + tam); 
      System.out.println("Recibiendo archivo2 " + nombreArchivo + tam); 
      // Creamos flujo de salida, este flujo nos sirve para 
      // indicar donde guardaremos el archivo 
      FileOutputStream fos = new FileOutputStream("/home/ubuntu/Documentos/Recibido/" + nombreArchivo); 
      BufferedOutputStream out = new BufferedOutputStream(fos); 
      BufferedInputStream in = new BufferedInputStream(yo.getInputStream()); 
      // Creamos el array de bytes para leer los datos del archivo 
      byte[] buffer = new byte[tam]; 
      // Obtenemos el archivo mediante la lectura de bytes enviados 
      for (int i = 0; i < buffer.length; i++) { 
       buffer[ i ] = (byte)in.read(); 
      } 
      // Escribimos el archivo 
      out.write(buffer); 
      // Cerramos flujos 
      out.flush(); 
      in.close(); 
      out.close(); 
      yo.close(); 
      System.out.println("Archivo Recibido " + nombreArchivo); 
     } catch (IOException e) { 
      System.err.println(e.getMessage()); 
      System.exit(1); 
     } 
    } 
} 

服務器:

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.text.SimpleDateFormat; 
import java.util.Calendar; 
import java.util.Scanner; 
import java.net.*; 
import java.io.*; 
public class MultiThreadedSocketServer { 
    ServerSocket myServerSocket; 
    boolean ServerOn = true; 
    String Archivo = "" ; 
    public MultiThreadedSocketServer() { 
     try { 
      myServerSocket = new ServerSocket(400); 
     } catch (IOException ioe) { 
      System.out.println("Error en la creacion del socket"); 
      System.exit(-1); 
     } 
     Calendar now = Calendar.getInstance(); 
     SimpleDateFormat formatter = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz"); 
     System.out.println("Hora de Inicio del Servidor : " + formatter.format(now.getTime())); 
     System.out.println("Esperando Conexiones " + formatter.format(now.getTime())); 
     System.out.println("*************************** \n"); 
     // Successfully created Server Socket. Now wait for connections. 
     while (ServerOn) { 
      try { 
       // Accept incoming connections. 
       Socket clientSocket = myServerSocket.accept(); 
       // accept() will block until a client connects to the server. 
       // If execution reaches this point, then it means that a client 
       // socket has been accepted. 
       // For each client, we will start a service thread to 
       // service the client requests. This is to demonstrate a 
       // Multi-Threaded server. Starting a thread also lets our 
       // MultiThreadedSocketServer accept multiple connections simultaneously. 
       // Start a Service thread 
       ClientServiceThread cliThread = new ClientServiceThread(clientSocket); 
       cliThread.start(); 
      } catch (IOException ioe) { 
       System.out.println("Exception encountered on accept. Ignoring. Stack Trace :"); 
       ioe.printStackTrace(); 
      } 
     } 
     try { 
      myServerSocket.close(); 
      System.out.println("Server Detenido"); 
     } catch (Exception ioe) { 
      System.out.println("Problema con el Socket , el server se detuvo"); 
      System.exit(-1); 
     } 
    } 
    public static void main (String[] args) { 
     new MultiThreadedSocketServer(); 
    } 
    class ClientServiceThread extends Thread { 
     Socket myClientSocket; 
     boolean m_bRunThread = true; 
     public ClientServiceThread() { 
      super(); 
     } 
     ClientServiceThread(Socket s) { 
      myClientSocket = s; 
     } 
     public void run() { 
      // Obtain the input stream and the output stream for the socket 
      // A good practice is to encapsulate them with a BufferedReader 
      // and a PrintWriter as shown below. 
      BufferedReader in = null; 
      PrintWriter out = null; 
      // Print out details of this connection 
      System.out.println("Cliente Conectado IP : " + myClientSocket.getInetAddress() + " Puerto: " + myClientSocket.getLocalPort()); 
      try { 
       in = new BufferedReader(new InputStreamReader(myClientSocket.getInputStream())); 
       out = new PrintWriter(new OutputStreamWriter(myClientSocket.getOutputStream())); 
       // At this point, we can read for input and reply with appropriate output. 
       // Run in a loop until m_bRunThread is set to false 
       while (m_bRunThread) { 
        // read incoming stream 
        String clientCommand = in.readLine(); 
        if (clientCommand.trim() == "Salir") { 
         System.out.println("Cliente IP : " + myClientSocket.getInetAddress() + " Puerto: " + myClientSocket.getLocalPort()); 
        } else { 
         System.out.println("Cliente IP : " + myClientSocket.getInetAddress() + " Puerto: " + myClientSocket.getLocalPort()); 
         System.out.println("El cliente solicita el archivo :" + clientCommand); 
         Archivo = clientCommand; 
        } 
        if (!ServerOn) { 
         // Special command. Quit this thread 
         System.out.print("El Servidor se encuentra detenido"); 
         out.println("El Servidor se encuentra detenido"); 
         out.flush(); 
         m_bRunThread = false; 
        } 
        if (clientCommand.equalsIgnoreCase("Salir")) { 
         // Special command. Quit this thread 
         m_bRunThread = false; 
         System.out.println("Cliente IP : " + myClientSocket.getInetAddress() + " Puerto: " + myClientSocket.getLocalPort()); 
         System.out.print("Salida del Cliente : "); 
        } else if (clientCommand.equalsIgnoreCase("apagar")) { 
         // Special command. Quit this thread and Stop the Server 
         m_bRunThread = false; 
         System.out.print("El servidor fue desconectado "); 
         ServerOn = false; 
        } else { 
         // Process it 
         out.println("Enviando el archivo: " + clientCommand); 
         out.flush(); 
         try { 
          // Creamos el Socket con la direccion y elpuerto de comunicacion 
          myClientSocket.setSoTimeout(2000); 
          myClientSocket.setKeepAlive(true); 
          Archivo = "/home/ubuntu/Documentos/" + clientCommand; 
          // Creamos el archivo que vamos a enviar 
          File archivo = new File(Archivo); 
          // Obtenemos el tamano del archivo 
          int tamanoArchivo = (int)archivo.length(); 
          System.out.println("Tamano del archivo: " + tamanoArchivo); 
          // Creamos el flujo de salida, este tipo de flujo nos permite 
          // hacer la escritura de diferentes tipos de datos tales como 
          // Strings, boolean, caracteres y la familia de enteros, etc. 
          DataOutputStream dos = new DataOutputStream(myClientSocket.getOutputStream()); 
          System.out.println("Enviando Archivo: " + clientCommand); 
          // Enviamos el nombre del archivo 
          dos.writeUTF(Archivo); 
          // Enviamos el tamano del archivo 
          dos.writeInt(tamanoArchivo); 
          // Creamos flujo de entrada para realizar la lectura del archivo en bytes 
          FileInputStream fis = new FileInputStream(archivo); 
          BufferedInputStream bis = new BufferedInputStream(fis); 
          // Creamos el flujo de salida para enviar los datos del archivo en bytes 
          BufferedOutputStream bos = new BufferedOutputStream(myClientSocket.getOutputStream()   ); 
          // Creamos un array de tipo byte con el tamano del archivo 
          byte[] buffer = new byte[tamanoArchivo]; 
          // Leemos el archivo y lo introducimos en el array de bytes 
          bis.read(buffer); 
          // Realizamos el envio de los bytes que conforman el archivo 
          for (int i = 0; i < buffer.length; i++) { 
           bos.write(buffer[ i ]); 
          } 
          System.out.println("Archivo Enviado: " + archivo.getName()); 
          // Cerramos socket y flujos 
          bis.close(); 
          bos.close(); 
         } catch (Exception e) { 
          System.out.println(e.toString()); 
         } 
        } 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } finally { 
       // Clean up 
       try { 
        in.close(); 
        out.close(); 
        myClientSocket.close(); 
        System.out.println("Cliente Desconectado"); 
       } catch (IOException ioe) { 
        ioe.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
+2

您應該用英文撰寫您的意見,以便我們更好地理解您的代碼。 – John

+1

服務器或客戶端是否拋出異常? –

+0

寫作時你無法得到這個例外。當你閱讀時你可以得到它,但是因爲你沒有從服務器的任何地方讀取文件名,所以我沒有看到你如何從這個代碼中得到例外。也不可能如何工作。 – EJP

回答

2

這裏的問題是,你同時使用BufferedReader和同一插座上DataInputStreamBufferedReader填充其緩衝區並竊取至少部分以下數據,其中包括存檔名稱,長度和數據。所以,當readUTF()執行,流在接下來的事情是不是writeUTF().

書面存檔名稱你或許應該只使用writeUTF()readUTF()貫穿始終,擺脫BufferedReaderPrintWriter完全的。