Java IO服务器客户端读取和处理用户输入
我有一个简单的文件服务器和来自web的客户机代码,可以将文件发送到家庭局域网内的另一台笔记本电脑。现在,从服务器发送到客户端的文件是硬编码的,但是我想提示客户端的用户输入一个文件名,将其发送到服务器并发回指定的文件。我的代码如下所示: 服务器 这就是服务器的客户端代码IPAddress是参数s[0],在main方法中保存文件的路径是s[1]Java IO服务器客户端读取和处理用户输入,java,client-server,java-io,Java,Client Server,Java Io,我有一个简单的文件服务器和来自web的客户机代码,可以将文件发送到家庭局域网内的另一台笔记本电脑。现在,从服务器发送到客户端的文件是硬编码的,但是我想提示客户端的用户输入一个文件名,将其发送到服务器并发回指定的文件。我的代码如下所示: 服务器 这就是服务器的客户端代码IPAddress是参数s[0],在main方法中保存文件的路径是s[1] import java.net.*; import java.io.*; public class Client { public static
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.printlnconnected之后将其放入客户端
在服务器端,我把它放在outputStream=new BufferedOutputStreamclientSocket.getOutputStream之后;覆盖服务器类开头的硬编码文件名
inputStream = new BufferedInputStream(clientSocket.getInputStream());
fileInputStream = new FileInputStream(inputStream);
fileInputStream = new BufferedInputStream(fileInput);
一旦建立了连接,客户端处于空闲状态,无法输入某些内容,而服务器端在写入控制台新连接后什么也不做
我该如何解决这个问题呢?客户端向服务器发送文件名。因此,首先必须从套接字的输入流中提取文件名。要做到这一点,您需要为如何发送信息建立一个协议。这在处理TCP流时非常关键,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。;
导入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();
}
}
}
sry我想你回答了我的问题。我不想将文件从客户端发送到服务器,我想连接到服务器-连接后,客户端会出现一个输入文件名的提示。这个文件名应该发送到服务器,最后,服务器应该返回指定的文件。所以我想我必须在服务器中添加扫描仪socket.accept之后的side,对吗?但是在建立连接后如何输入文件名并将其发送到服务器?我理解这个问题。客户端只是将文件名发送到服务器。扫描程序只是获取文件名。我认为这是您实现中唯一可能出错的部分。在您的实现中,server从套接字获取InputStream并将其用作FileInputStream的输入。这就是问题所在。FileInputStream需要我们称之为文件名的文件路径作为输入。因此,首先从套接字的InputStream提取文件名,然后仅将文件名传递给FileInputStream。我将编辑我的答案w使用完整的客户端和服务器代码。这就是为什么我通过关闭服务器上的outputSteam来关闭套接字。这将向客户端发出文件已完全发送的信号。通常在tcp流中有定界符,但由于这是原始数据,因此不需要检查定界符(如两个换行符),因为它可能显示为非常感谢,命令现在到达了服务器,但之后我在客户端代码“java.net.SocketException:Socket在java.net.Socket.getInputStreamUnknown Source在client.mainclient.java:53”中遇到了一个异常,但客户端在此之后运行,并再次写入插入文件名进行下载
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();
}
}
}
}
}
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();
}
}
}