我正在使用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;
}
}
rmiregistry中
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);
}
}
ServerInterface:
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 Client localhost nameOfAPicture,例如:pic.jpg
。
答案 0 :(得分:0)
每次拨打escribirArchivos()
时,您都会创建一个新文件,而不是附加到该文件。所以文件总是与最后一次写入的大小相同。
很难看到从服务器读取文件然后将其复制两次。