java - 异常 : java. io.UTFDataFormatException:服务器/客户端

标签 java sockets

我正在编写我的第一个 java 客户端/服务器程序,它只是建立一个连接。客户端向其发送一个句子(文件名),服务器将文件发送给客户端。

但是当我尝试读取文件名时,出现此异常: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();
                }
            }
        }
    }
}

最佳答案

这里的问题是您在同一个套接字上同时使用 BufferedReaderDataInputStream。 BufferedReader 填充其缓冲区并窃取至少部分以下数据,其中包括存档名称、长度和数据。因此,当 readUTF() 执行时,流中的下一个内容不是 writeUTF() 写入的存档名称。

您可能应该只使用 writeUTF()readUTF() ,并摆脱 BufferedReaderPrintWriter 完全。

关于java - 异常 : java. io.UTFDataFormatException:服务器/客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23179066/

相关文章:

Java Math.acos() 返回值

java - 如何为一组方法编写单元测试,其中每个方法都依赖于其他方法?

python - PAIR/PAIR 通信原型(prototype)中的 PyZMQ 用户输入()

java - 创建 RTP 数据包

java - 导入类 Java 问题 Minecraft 插件

java - 应用引擎 : How to persist related entities using Objectify

java - 如何通过套接字 C++ 服务器/Java 客户端发送 int

c++ - Unix 多播套接字线程安全吗?

c - TCP/IP : message got by recv() in order without keep buffer

java - 是否可以在不使用 RMI 的情况下要求服务器端执行某个方法?