我有一个简单的文件服务器和客户端(来自网络的代码),可以让我将文件发送到我家局域网内的另一台笔记本电脑。现在,从服务器发送到客户端的文件是硬编码的,但我想提示客户端的用户输入文件名,将其发送到服务器并发回指定的文件。我的代码如下所示:
服务器
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) {
BufferedOutputStream outputStream;
BufferedInputStream inputStream;
FileInputStream fileInput;
String file = "C:/java/file.mp4";
try {
ServerSocket socket = new ServerSocket(12345);
while(true) {
Socket clientSocket = socket.accept();
outputStream = new BufferedOutputStream(clientSocket.getOutputStream());
fileInput = new FileInputStream(file);
inputStream = new BufferedInputStream(fileInput);
int packetToSend = -1;
byte[] buffer = new byte[8192];
while((packetToSend = inputStream.read(buffer)) > -1) {
outputStream.write(buffer, 0, packetToSend);
System.out.println("sending " + packetToSend + " bytes");
outputStream.flush();
}
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}
这就是客户端代码(服务器的 IPA地址是参数 s[0],保存文件的路径是 main 方法中的 s[1]。
import java.net.*;
import java.io.*;
public class Client {
public static void main(String[] s) {
try {
String address = new String(s[0]);
String fileToSave = new String(s[1]);
Socket socket = new Socket(address,12345);
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
FileOutputStream fos = new FileOutputStream(fileToSave);
int n;
byte[] buffer = new byte[8192];
System.out.println("Connected");
while ((n = bis.read(buffer)) > 0) {
System.out.println("received "+n+" bytes");
fos.write(buffer, 0, n);
fos.flush();
}
System.out.println("recieved");
}
catch(Exception e) {
e.printStackTrace();
}
}
}
我想让客户端的用户在客户端连接后输入文件名以发送到服务器,服务器应该发送该文件。
我试图在System.out.println("connected");
后将其放在客户端
System.out.print("Insert filename to download: ");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String input = null;
try {
input = reader.readLine();
} catch (IOException ioe) {
System.out.println("Eingabe konnte nicht verarbeitet werden!");
System.exit(1);
}
System.out.println("Eingabe: " + input);
在服务器端,我将其放在outputStream = new BufferedOutputStream(clientSocket.getOutputStream());
之后,以覆盖服务器类开头的硬编码文件名。
inputStream = new BufferedInputStream(clientSocket.getInputStream());
fileInputStream = new FileInputStream(inputStream);
fileInputStream = new BufferedInputStream(fileInput);
建立连接后,客户端处于空闲状态(无法输入某些内容),服务器端在写出控制台"新连接"后不执行任何操作。
请问我该如何解决这个问题?
客户端将文件名发送到服务器。 因此,首先您必须从套接字的输入流中提取文件名。 为此,您需要为如何发送信息建立一个协议。 这在处理 TCP 流时至关重要,这与 UDP 数据报不同。 通常使用两个换行符来传达消息的结尾。 但是由于文件名中有一个换行符是不正常的,我们将使用一个换行符来传达消息的结尾。
然后,我们可以使用 Scanner 从客户端的套接字中提取文件名。
String fileName;
Scanner scanner = new Scanner (clientSocket.getInputStream());
while(scanner.hasNextLine())
{
fileName = scanner.nextLine();
break;
}
fileInputStream = new FileInputStream(fileName);
fileInputStream = new BufferedInputStream(fileInput);
在此示例中,文件名必须是该文件的绝对路径,因为它位于服务器的文件系统中。 在将来的版本中,您可能希望在存储文件的服务器上使用目录,客户端可以为您提供该目录中文件的相对路径。 这是它的样子。
String fileName;
Scanner scanner = new Scanner (clientSocket.getInputStream());
while(scanner.hasNextLine())
{
fileName = scanner.nextLine();
break;
}
fileInputStream = new FileInputStream(FILE_DIR + fileName);
fileInputStream = new BufferedInputStream(fileInput);
变量FILE_DIR如下所示:
static String FILE_DIR = "C:/java/";
客户端发送的文件将file.mp4
编辑 1:
下面是包含建议的客户端代码。 请注意,此测试质量代码,而不是生产代码。
import java.net.*;
import java.io.*;
public class Client {
static String FILE_DIR = "./";
public static void main(String[] s) throws IOException {
/**
* Establish socket using main args.
*/
String address = s[0];
while (true) {
/**
* Get the file name from the user.
*/
System.out.print("Insert filename to download: ");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String fileName = null;
try {
fileName = reader.readLine();
} catch (IOException ioe) {
System.out.println("Eingabe konnte nicht verarbeitet werden!");
System.exit(1);
}
System.out.println("Eingabe: " + fileName);
/**
* Create the socket.
*/
Socket socket = new Socket(address, 12345);
/**
* With file name in hand, proceed to send the filename to the
* server.
*/
//...put in try-with-resources to close the outputstream.
try (BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream())) {
System.out.println("Connected: Sending file name to server.");
//...send file name plus a newline.
bos.write((fileName + 'n').getBytes());
bos.flush();
/**
* Get the file contents and save to disk.
*/
//...wrap input stream in DataInpuStream for portability.
//...put in try-with-resource to close the input stream.
try (BufferedInputStream bis = new BufferedInputStream(new DataInputStream(socket.getInputStream()))) {
DataOutputStream fos = new DataOutputStream(new FileOutputStream(fileName));
int n;
byte[] buffer = new byte[8192];
System.out.println("Connected: Recieving file contents from server.");
while ((n = bis.read(buffer)) > 0) {
System.out.println("received " + n + " bytes");
fos.write(buffer, 0, n);
fos.flush();
}
System.out.println("recieved");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
这是服务器代码。 请注意,服务器正在从名为./files/的本地目录中检索文件,请将其更改为所需的任何目录。
导入 java.net。;进口 java.io.;import java.util.Scanner;
公共类服务器 {
static String FILE_DIR = "./files/";
public static void main(String[] args) {
BufferedInputStream inputStream;
FileInputStream fileInput;
try {
ServerSocket socket = new ServerSocket(12345);
while (true) {
Socket clientSocket = socket.accept();
/**
* Get the file name from the client. File name is one per line.
*/
//...put in trye-with-resources to close InputStream for us.
try (InputStream inputFromClient = clientSocket.getInputStream()) {
System.out.println("Connected: Getting file name from client.");
Scanner scanner = new Scanner(inputFromClient);
String fileName;
if (scanner.hasNextLine()) {
fileName = scanner.nextLine();
System.out.println("File name = " + fileName);
} else {
//...no line found, continue. consider logging an error or warning.
continue;
}
/**
* With fileName in hand, we can proceed to send the
* contents of the file to the client.
*/
fileInput = new FileInputStream(fileName);
//...use DataInputStream for more portable code
DataInputStream dataInput = new DataInputStream(fileInput);
inputStream = new BufferedInputStream(dataInput);
int packetToSend = -1;
byte[] buffer = new byte[8192];
//...consider closing the OutputStream to let the client know.
//...use try-with-resource to close the outputStream for us.
//...wrap your outputStream in DataOutputStream
try (BufferedOutputStream outputStream = new BufferedOutputStream(new DataOutputStream(clientSocket.getOutputStream()))) {
while ((packetToSend = inputStream.read(buffer)) > -1) {
outputStream.write(buffer, 0, packetToSend);
System.out.println("sending " + packetToSend + " bytes");
outputStream.flush();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}