简体   繁体   中英

Exception: java.io.UTFDataFormatException: Server /Client

I'm writing my first java client/server program which just establishes a connection. The client sends it a sentence (file name) and the server sends the file to client.

But when I try to read the name of the file, I get this exception: java.io.UTFDataFormatException: malformed input around byte 65 .

Client:

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);
        }
    }
}

Server:

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();
                }
            }
        }
    }
}

The problem here is that you are using both a BufferedReader and a DataInputStream on the same socket. BufferedReader fills its buffer and steals at least part of the following data, which includes the archive name, the length, and the data. So when readUTF() executes, the next thing in the stream isn't the archive name written by writeUTF().

You should probably just use writeUTF() and readUTF() throughout, and get rid of the BufferedReader and PrintWriter altogether.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM