如果要发送的文件不是普通文本文件,则Java-File send through socket为空
我已经创建了一个程序,将向客户端发送一个文件。我对普通文本文件进行了测试,它已完全发送到客户端,没有丢失。但是当我尝试发送一些zip文件时,输出文件是空的。我该怎么办 Server.java如果要发送的文件不是普通文本文件,则Java-File send through socket为空,java,Java,我已经创建了一个程序,将向客户端发送一个文件。我对普通文本文件进行了测试,它已完全发送到客户端,没有丢失。但是当我尝试发送一些zip文件时,输出文件是空的。我该怎么办 Server.java import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; class Server { public static void main(String[] arg
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
Scanner scan = new Scanner(System.in);
String fileSend;
System.out.print("Type the path to the file to send >> ");
fileSend = scan.nextLine();
try {
serverSocket = new ServerSocket(5467);
} catch (Exception e) {
System.out.println("Could not bind to port 5467, Maybe address is already is use or you need to run as administrator");
scan.close();
return;
}
System.out.println("Listening on port 5467");
System.out.println("Waiting for the connection...");
while (true) {
File FileSend = null;
Socket socket = serverSocket.accept();
OutputStream out = socket.getOutputStream();
System.out.println("Accepted connection : " + socket);
//รับข้อมูลจาก Client เข้ามา
InputStream in = socket.getInputStream();
DataInputStream dataIn = new DataInputStream(in);
String login = dataIn.readUTF();
String password = dataIn.readUTF();
String result = "You credential is ";
if (login.equals("1c18b5cdef8f9b4c5d6b2ad087265e597d1d4639337b73a04a335103c00ec64b") && password.equals("1c18b5cdef8f9b4c5d6b2ad087265e597d1d4639337b73a04a335103c00ec64b13d0b73358bfa8978dfaaf180565bcfecd3dc0631cda525920865145fb3fa131")) {
result += "correct";
} else {
result += "incorrect";
}
DataOutputStream dataOut = new DataOutputStream(out);
dataOut.writeUTF(result);
FileSend = new File(fileSend);
ObjectOutputStream out1 = new ObjectOutputStream(socket.getOutputStream());
System.out.println("Sending file...");
out1.writeObject(FileSend);
//ส่งข้อมูลกลับไปยัง Client
}
}
}
Client.java
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Client {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, ClassNotFoundException {
Socket socket = null;
String PlainLogin;
String FileOut;
String PlainPassword;
Scanner scan = new Scanner(System.in);
System.out.print("What is the IP address of the server >> ");
String host = scan.nextLine();
try {
socket = new Socket(host, 5467); //หรือกำหนดเป็น 127.0.0.1
} catch (ConnectException | NullPointerException e) {
System.out.println("Connection Refused, Have you run the server first?");
scan.close();
return;
}
OutputStream out = socket.getOutputStream();
DataOutputStream dataOut = new DataOutputStream(out);
System.out.println("Connection Established");
System.out.println("Credential Required, Please login");
System.out.print("Type your username >> ");
PlainLogin = scan.next();
System.out.print("Type your password >> ");
PlainPassword = scan.next();
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hashInBytes = md.digest(PlainLogin.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : hashInBytes) {
sb.append(String.format("%02x", b));
}
String HashedLogin = sb.toString();
byte[] hashInBytesP = md.digest(PlainPassword.getBytes(StandardCharsets.UTF_8));
for (byte b : hashInBytesP) {
sb.append(String.format("%02x", b));
}
String HashedPassword = sb.toString();
dataOut.writeUTF(HashedLogin); //ลำดับในการส่งข้อมูล ต้องตรงกับลำดับในการรับข้อมูลทางฝั่ง Server
dataOut.writeUTF(HashedPassword);
InputStream in = socket.getInputStream();
DataInputStream dataIn = new DataInputStream(in);
String str = dataIn.readUTF();
if (str == "Your credential is incorrect") {
System.out.println(str);
socket.close();
scan.close();
return;
} else {
System.out.println(str);
// Writing the file to disk
// Instantiating a new output stream object
System.out.print("Type any file name you want >> ");
scan.nextLine();
FileOut = scan.nextLine();
File SaveFile = new File(FileOut);
ObjectInputStream in1 = new ObjectInputStream(socket.getInputStream());
File receivedFile = null;
receivedFile = (File) in1.readObject();
Scanner sc = new Scanner(receivedFile);
PrintWriter printer = new PrintWriter(SaveFile);
while(sc.hasNextLine()) {
String s = sc.nextLine();
printer.write(s);
}
socket.close();
dataIn.close();
printer.close();
sc.close();
scan.close();
System.out.println("Done");
}
}
}
我希望zip文件被发送并且没有损坏,但是输出时文件是空的。您正在使用对象流发送
文件
对象。那不是你想象的那样。文件
是表示文件系统路径名的对象。它不表示文件的内容
因此,您的代码实际上做的是:
- 发送散列用户名和密码
- 在服务器端检查它们
- 发送
文件
- 在服务器端,“打开”
并复制其内容文件
文件
,因此没有数据从客户端复制到服务器
您还使用了扫描仪
来复制(错误的)文件。一般来说,这对于非文本文件来说是不正确的。不管数据的“类型”如何,复制数据最安全的方法是使用二进制流
如果要发送文件内容,请不要使用ObjectInputStream
和ObjectOutputStream
发送路径名。相反,使用普通的OutputStream::write(…)
和OutputStream::read(…)
和循环来复制文件数据:
- 客户端应从(客户端)本地文件读取字节,并复制到套接字流
- 服务器端应该从套接字读取字节并写入(服务器端)本地文件
ObjectOutputStream
发送文件?扫描仪是为文本文件设计的,不能很好地处理二进制文件。此外,您只通过套接字发送文件的路径,而不是实际的文件内容本身。