Java 通过套接字传输多个文件问题
服务器端:Java 通过套接字传输多个文件问题,java,Java,服务器端: public class Server { public static final String ALGORITHM = "RSA"; public static final String PRIVATE_KEY_FILE = "C:/Users/mrarsenal10/Desktop/server/key/private.key"; public static final String PUBLIC_KEY_FILE = "C:/Users/mrarsenal10/Desktop
public class Server
{
public static final String ALGORITHM = "RSA";
public static final String PRIVATE_KEY_FILE = "C:/Users/mrarsenal10/Desktop/server/key/private.key";
public static final String PUBLIC_KEY_FILE = "C:/Users/mrarsenal10/Desktop/server/key/public.key";
public static void generateKey()
{
try
{
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
keyGen.initialize(1024);
final KeyPair key = keyGen.generateKeyPair();
File privateKeyFile = new File(PRIVATE_KEY_FILE);
File publicKeyFile = new File(PUBLIC_KEY_FILE);
// Create files to store public and private key
if (privateKeyFile.getParentFile() != null) {
privateKeyFile.getParentFile().mkdirs();
}
privateKeyFile.createNewFile();
if (publicKeyFile.getParentFile() != null) {
publicKeyFile.getParentFile().mkdirs();
}
publicKeyFile.createNewFile();
// Saving the Public key in a file
ObjectOutputStream publicKeyOS = new ObjectOutputStream(
new FileOutputStream(publicKeyFile));
publicKeyOS.writeObject(key.getPublic());
publicKeyOS.close();
// Saving the Private key in a file
ObjectOutputStream privateKeyOS = new ObjectOutputStream(
new FileOutputStream(privateKeyFile));
privateKeyOS.writeObject(key.getPrivate());
privateKeyOS.close();
}catch (Exception e)
{
e.printStackTrace();
}
}
public static boolean areKeysPresent()
{
File privateKey = new File(PRIVATE_KEY_FILE);
File publicKey = new File(PUBLIC_KEY_FILE);
if (privateKey.exists() && publicKey.exists())
{
return true;
}
return false;
}
public static String decrypt(byte[] text, PrivateKey key) { // giải mã
byte[] dectyptedText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// decrypt the text using the private key
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
} catch (Exception ex) {
ex.printStackTrace();
}
return new String(dectyptedText);
}
static void sendFile(Socket sock, String fName) throws FileNotFoundException, IOException
{
File transferFile = new File (fName);
byte [] bytearray = new byte [(int)transferFile.length()];
FileInputStream fin = new FileInputStream(transferFile);
BufferedInputStream bin = new BufferedInputStream(fin);
bin.read(bytearray,0,bytearray.length); // luu vao bytearray
OutputStream os = sock.getOutputStream(); // goi outputstream de
System.out.println("Sending Files...");
os.write(bytearray,0,bytearray.length);
os.flush();
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
if (!areKeysPresent()) {
generateKey();
}
ServerSocket serverSocket = new ServerSocket(15124);
Socket sock = serverSocket.accept();
sendFile(sock, PUBLIC_KEY_FILE);
sendFile(sock, "lich.txt");
sock.close();
}
}
客户端:
public class Client
{
public static final String ALGORITHM = "RSA";
public static final String PUBLIC_KEY_FILE = "C:/Users/mrarsenal10/Desktop/Client/public.key";
static void recvFile(Socket sock, String fName) throws FileNotFoundException, IOException
{
int filesize=1022386;
int bytesRead;
int currentTot = 0;
byte [] bytearray = new byte [filesize];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream(fName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(bytearray,0,bytearray.length);
currentTot = bytesRead;
do {
bytesRead = is.read(bytearray, currentTot, (bytearray.length-currentTot));
if(bytesRead >= 0) currentTot += bytesRead; }
while(bytesRead > -1);
bos.write(bytearray, 0 , currentTot);
bos.flush();
bos.close();
}
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Socket sock = new Socket("127.0.0.1",15124);
recvFile(sock, "public.key");
recvFile(sock, "lich.txt");
sock.close();
}
}
我的问题是在这里我只能发送“public.key”或“lich.txt”从服务器到客户端,现在我想同时发送“public.key”和“lich.txt”。感谢您的帮助。问题在于服务器和客户端的总体设计。在服务器端,它发送两个不同的文件,但在客户端,它只是一个数据流。一个字节表示一个文件中的数据与下一个文件中的数据没有区别。因此,您可能正在调用recvFile,它从服务器发送的两个文件接收所有数据。发送数据后,服务器关闭连接。(您可以显式地执行此操作。)因此,在客户端,您有一个无效的套接字。但是,您尝试使用表示第二个文件的套接字思想再次调用recvFile。这将导致您看到的SocketException或更可能的OutOfBoundsException 要解决这个问题,您需要在服务器和客户端之间添加更多的握手。最简单的是表示文件结尾的分隔符。更好的方法是在发送任何数据之前,在每个“消息”(也称为文件)的前面附加一个已知大小的头,让客户机知道文件的大小。然后,一旦客户端接收到报头,它就确切地知道要读取多少字节 现在,为了防止崩溃,您将
recvFile
方法更改为如下内容:
byte[] bytearray = new byte[4096];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream(fName);
int bytesRead;
while ((bytesRead = is.read(bytearray)) >= 0) {
if (bytesRead > 0) {
fos.write(bytearray, 0, bytesRead);
}
}
fos.flush();
fos.close();
我已经对你的问题做了一些小的编辑,但是你应该强烈地考虑改写这个问题,并对它进行重新格式化,使我们更容易理解。