复制文件客户机服务器 java rmi



我正在用SSL制作一个简单的客户端-服务器rmi应用程序。代码工作正常,但是当我复制一个重量为 58kb 的文件时,它会生成一个权重为 1kb 的副本。

我快疯了。我将不胜感激任何帮助。这是代码:

客户:

package tpfinal;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import javax.rmi.ssl.SslRMIClientSocketFactory;
public class Client {
    public static void main (String[] args) throws FileNotFoundException, IOException {
        if (args.length < 2) {
            System.out.println("Se necesitan dos argumentos: Hostname y Filename");
            System.exit(1);
        }
        try {
            System.setProperty("javax.net.ssl.keyStore","C:\Users\Lucho\workspace\Distribuida\bin\keystore");
            System.setProperty("javax.net.ssl.keyStorePassword","123456");
            System.setProperty("javax.net.ssl.trustStore","C:\Users\Lucho\workspace\Distribuida\bin\truststore");
            System.setProperty("javax.net.ssl.trustStorePassword","123456");
            Registry registry = LocateRegistry.getRegistry(null, ServerInterface.PORT, new SslRMIClientSocketFactory());
            ServerInterface server = (ServerInterface) registry.lookup("SSLServer");
            int bufferSize = 1024;
            int pos = 0;
            Respuesta respuesta = new Respuesta();
            String serverPath = System.getProperty("user.dir") + System.getProperty("file.separator") + args[1];
            String clientCopyPath = System.getProperty("user.dir") + System.getProperty("file.separator") + "clicopia1-" + args[1];
            String serverCopyPath = System.getProperty("user.dir") + System.getProperty("file.separator") + "sercopia2-" + args[1];
            System.out.println(serverPath + " serverPath");
            System.out.println(clientCopyPath + " clientCopyPath");
            respuesta = server.leerArchivo(serverPath, pos, bufferSize);
            while (respuesta.getLeidos() > 0) {
                if (server.escribirArchivo(clientCopyPath, respuesta.getLeidos(), respuesta.getBuffer()) == -1) {
                    System.out.println("Se produjo un error al abrir el archivo copia1");
                }
                if (server.escribirArchivo(serverCopyPath, respuesta.getLeidos(), respuesta.getBuffer()) == -1) {
                    System.out.println("Se produjo un error al abrir el archivo copia2");
                }
                pos += respuesta.getLeidos();
                respuesta = server.leerArchivo(serverPath, pos, bufferSize);
                System.out.println(pos);
            }
            if (respuesta.getLeidos() == -1) {
                System.out.println("Se produjo un error al abrir el archivo original");
            }
        } catch (AccessException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (NotBoundException e) {
            e.printStackTrace();
        }
    }
}

服务器:

package tpfinal;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
public class Server extends UnicastRemoteObject implements ServerInterface {
    protected Server() throws RemoteException{
        super(0, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory(null, null, true));
    }

    public static void main(String[] args) {
        try {
            System.setProperty("javax.net.ssl.keyStore","C:\Users\Lucho\workspace\Distribuida\bin\keystore");
            System.setProperty("javax.net.ssl.keyStorePassword","123456");
            System.setProperty("javax.net.ssl.trustStore","C:\Users\Lucho\workspace\Distribuida\bin\truststore");
            System.setProperty("javax.net.ssl.trustStorePassword","123456");
            Registry registry = LocateRegistry.getRegistry(null, ServerInterface.PORT, new SslRMIClientSocketFactory());
            Server server = new Server();
            registry.rebind("SSLServer", server);
            System.out.println("SSLServer bound in registry");
        } catch (Exception e) {
            System.out.println("SSLServer error: " + e.getMessage());
            e.printStackTrace();
        }
    }
    @Override
    public Respuesta leerArchivo(String fileName, int pos, int cant)
            throws RemoteException, FileNotFoundException, IOException {
        File archivo = new File(fileName);
        Respuesta respuesta = new Respuesta();
        respuesta.setLeidos(-1);
        respuesta.setPedidos(cant);
        if (archivo.exists() && archivo.setReadOnly()) {
            FileInputStream in = new FileInputStream(archivo);
            in.skip(pos); // Descartamos lo leído.
            respuesta.setLeidos(in.read(respuesta.getBuffer(), 0, cant));
            if (respuesta.getLeidos() == -1) {
                respuesta.setLeidos(0);             
            }
            in.close();
        }
        return respuesta;
    }
    @Override
    public int escribirArchivo(String fileName, int cant, byte[] data)
            throws RemoteException, FileNotFoundException, IOException {
        File archivo = new File(fileName);
        FileOutputStream out = new FileOutputStream(archivo);
        out.write(data, 0, cant);
        out.close();
        return cant;
    }
}

Rmi注册表

package tpfinal;
import java.rmi.registry.LocateRegistry;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
public class RmiRegistry {
    public static void main(String[] args) throws Exception {
        System.out.println("Rmi Registry running on port " + ServerInterface.PORT);
        System.setProperty("javax.net.ssl.keyStore","C:\Users\Lucho\workspace\Distribuida\bin\keystore");
        System.setProperty("javax.net.ssl.keyStorePassword","123456");
        System.setProperty("javax.net.ssl.trustStore","C:\Users\Lucho\workspace\Distribuida\bin\truststore");
        System.setProperty("javax.net.ssl.trustStorePassword","123456");
        LocateRegistry.createRegistry(ServerInterface.PORT,new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory(null, null, true));
        //Sleep
        Thread.sleep(Long.MAX_VALUE);
    }
}

服务器接口:

package tpfinal;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ServerInterface extends Remote {
    int PORT = 8844;
    public Respuesta leerArchivo(String fileName, int pos, int cant) throws RemoteException, FileNotFoundException, IOException;
    public int escribirArchivo(String fileName, int cant, byte[] data) throws RemoteException, FileNotFoundException, IOException;
}

响应:

package tpfinal;
import java.io.Serializable;
public class Respuesta implements Serializable{
    private static final long serialVersionId = 1L;
    int pedidos;
    int leidos;
    byte[] buffer = new byte[1024];
    public int getPedidos() {
        return pedidos;
    }
    public void setPedidos(int pedidos) {
        this.pedidos = pedidos;
    }
    public int getLeidos() {
        return leidos;
    }
    public void setLeidos(int leidos) {
        this.leidos = leidos;
    }
    public byte[] getBuffer() {
        return buffer;
    }
    public void setBuffer(byte[] buffer) {
        this.buffer = buffer;
    }
}

代码工作正常,但我找不到这个问题。如果有人想尝试,您可以删除 System.setProperty,这样就不需要创建密钥库和信任库。客户端必须像这样执行:java 客户端本地主机名OfAPicture,例如:pic.jpg

每次调用escribirArchivos()时,您都在创建一个新文件,而不是附加到该文件。因此,文件的大小始终是上次写入它的大小。

很难看到从服务器读取文件然后将其复制回两次的意义。

最新更新