问题
In my client-server application, when I try to download a file from the serverSide, the file gets downloaded; but the header information such as some additional text with line break can't be read. As you can see in my Server class this following information is supposed to be printed out in the client side.
outputToClient.printf("Status OK\r\nSize %d Bytes\r\n\r\nFile %s Download was successfully\r\n",
fileSize, filename);
But it doesn't. Only the fisrt string (Status OK
) before the \r\n
gets printed, not any string after \r\n
.
How can I fix it?
My complete code:
ServerSide:
public class ServerSide {
private BufferedReader inputFromClient;
private PrintWriter outputToClient;
private FileInputStream fis;
private OutputStream os;
private static final int PORT = 8000;
private ServerSocket serverSocket;
private Socket socket;
public static void main(String[] args) {
int port = PORT;
if (args.length == 1) {
port = Integer.parseInt(args[0]);
}
new ServerSide(port);
}
private boolean fileExists(File[] files, String filename) {
boolean exists = false;
for (File file : files) {
if (filename.equals(file.getName())) {
exists = true;
}
}
return exists;
}
public ServerSide(int port) {
// create a server socket
try {
serverSocket = new ServerSocket(port);
} catch (IOException ex) {
System.out.println("Error in server socket creation.");
System.exit(1);
}
while (true) {
try {
socket = serverSocket.accept();
outputToClient = new PrintWriter(socket.getOutputStream());
inputFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
String request = inputFromClient.readLine();
if (!request.startsWith("exit") && !request.startsWith("pwd") && !request.startsWith("list") && !request.startsWith("GET")) {
outputToClient.println("Wrong request\r\n"
+ "\r\n");
} else if (request.startsWith("exit")) {
break;
} else if (request.startsWith("pwd")) {
File file = new File(System.getProperty("user.dir"));
outputToClient.print("Status OK\r\n"
+ "Lines 1\r\n"
+ "\r\n"
+ "Working dir: " + file.getName() + "\r\n");
} else if (request.startsWith("list")) {
File file = new File(System.getProperty("user.dir"));
File[] files = file.listFiles();
outputToClient.print("Status OK\r\n"
+ "Files " + files.length + "\r\n"
+ "\r\n"
+ Arrays.toString(files).substring(1, Arrays.toString(files).length() - 1) + "\r\n");
} else if (request.startsWith("GET")) {
String filename = request.substring(4);
File file = new File(System.getProperty("user.dir"));
File[] files = file.listFiles();
if (fileExists(files, filename)) {
file = new File(filename);
int fileSize = (int) file.length();
outputToClient.printf("Status OK\r\nSize %d Bytes\r\n\r\nFile %s Download was successfully\r\n",
fileSize, filename);
outputToClient.flush();
try (FileInputStream fis = new FileInputStream(file)) {
os = socket.getOutputStream();
byte[] buffer = new byte[(1 << 7) - 1];
int bytesRead = 0;
while ((bytesRead = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
}
//os.close();
// fis.close();
} else {
outputToClient.print("Status 400\r\n"
+ "File " + filename + " not found\r\n"
+ "\r\n");
outputToClient.flush();
}
}
outputToClient.flush();
}
} catch (IOException e) {
System.err.println(e);
}
}
}
}
ClientSide:
public class ClientSide {
private static Socket socket;
private static PrintWriter outputToServer;
private static BufferedReader inputFromServer;
private static InputStream is;
private static FileOutputStream fos;
private static final int PORT = 8000;
private static final String SERVER = "85.197.159.45";
boolean Connected;
DataInputStream serverInput;
public static void main(String[] args) throws InterruptedException {
String server = "localhost";
int port = PORT;
if (args.length >= 1) {
server = args[0];
}
if (args.length >= 2) {
port = Integer.parseInt(args[1]);
}
new ClientSide(server, port);
}
public ClientSide(String server, int port) {
try {
socket = new Socket(server, port);
serverInput = new DataInputStream(socket.getInputStream());
outputToServer = new PrintWriter(socket.getOutputStream(), true);
inputFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Client is connected! ");
Connected = true;
String line = null;
Scanner sc = new Scanner(System.in);
System.out.print("Type command: ");
while (sc.hasNextLine()) {
String request = sc.nextLine();
if (request.startsWith("exit")) {
outputToServer.println(request);
System.out.println("Application exited!");
//outputToServer.flush();
break;
} else if (request.startsWith("pwd")) {
outputToServer.println(request);
outputToServer.flush();
} else if (request.startsWith("list")) {
outputToServer.println(request);
outputToServer.flush();
} else if (request.startsWith("GET")) {
System.out.print("\r\n");
outputToServer.println(request);
outputToServer.flush();
}
while (Connected) {
line = inputFromServer.readLine();
System.out.println(line);
if (line.isEmpty()) {
Connected = false;
if (inputFromServer.ready()) {
System.out.println(inputFromServer.readLine());
}
}
if (line.startsWith("Status 400")) {
while (!(line = inputFromServer.readLine()).isEmpty()) {
System.out.println(line);
}
break;
}
if (request.startsWith("GET")) {
File file = new File(request.substring(4));
is = socket.getInputStream();
fos = new FileOutputStream(file);
byte[] buffer = new byte[socket.getReceiveBufferSize()];
serverInput = new DataInputStream(socket.getInputStream());
//int bytesReceived = 0;
byte[] inputByte = new byte[4000];
int length;
while ((length = serverInput.read(inputByte, 0, inputByte.length)) > 0) {
fos.write(inputByte, 0, length);
}
request = "";
fos.close();
}
}
System.out.print("\nType command: ");
Connected = true;
}
outputToServer.close();
inputFromServer.close();
socket.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
回答1:
while (Connected) {
line = inputFromServer.readLine();
System.out.println(line);
if (line.isEmpty()) {
Connected = false;
if (inputFromServer.ready()) {
System.out.println(inputFromServer.readLine());
}
}
// ...
Usual misuse of ready().
Try this:
while ((line = inputFromServer.readLine()) != null)
System.out.println(line);
if (line.isEmpty()) {
Connected = false;
break;
}
// ...
NB You don't need the fileExists()
method at all, and you certainly don't need to write it like that. new FileInputStream()
will throw FileNotFoundException
if the file doesn't exist. Catch it.
回答2:
You should close the output stream outputToClient.close()
in ServerSide
after last outputToClient.flush()
In your client side you need to establish connection again, so move the connection part inside the loop.
来源:https://stackoverflow.com/questions/30429281/why-fileoutputstream-cant-output-any-string-after-an-empty-line-or-a-line-brea