As part of my Java course, I'm writing a server-client socket program that facilitates a file transfer. While the file transfer works fine, it always throws an exception whenever I try to close it from the client side.
The code for the server is as follows:
String client = "";
long size;
//set the connection checker and disconnector
boolean exit = false;
try {
System.out.println("Client passed to thread");
InputStream is = sock.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
DataInputStream dis = new DataInputStream(bis);
while (!exit) {
System.out.println("Client passed into while loop");
//put the stuff in a while loop
client = dis.readUTF();// can separate the types of input
size = dis.readLong();
if (client.equals("close".trim().toLowerCase())) {
System.out.println("Client disconnected");
dis.close();
bis.close();
is.close();
exit = true;
continue;
}
else {
System.out.println("File received: " + client + "\nFile size: " + size);
// fileoutput is tacked onto output stream directly
OutputStream os = new FileOutputStream(client);
// create output stream to write to the file
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] buffer = new byte[4 * 1024];
int receivedBytes = 0;
long remainingBytes = 0;
System.out.println(receivedBytes + " received...");
while ((receivedBytes = dis.read(buffer)) > 0) {
bos.write(buffer, 0, receivedBytes);
remainingBytes = size - receivedBytes;
System.out.println(receivedBytes + " received...\n" + remainingBytes + "left");
bos.flush();
exit = true;
}
bos.close();
os.close();
}
}
dis.close();
bis.close();
is.close();
// if (size < 20.0) {
// System.out.println("File size insufficient, please include more stuff");
// }
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
sock.close();
} catch (IOException e) {
}
}
And the client code is here:
String input = "";
long l = 1024;
int fileData;
Console cons = System.console();
Socket socket = new Socket(host, Integer.parseInt(port));
while (!("close").equals(input.trim().toLowerCase())) {
input = cons.readLine("Please indicate the file to be sent: \n");
OutputStream os = socket.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
DataOutputStream dos = new DataOutputStream(bos);
if (input.equals("close".trim().toLowerCase())) {
dos.writeUTF(input);
dos.writeLong(l);
dos.flush();
System.out.println("Gotcha. Disconnecting");
break;
}
File toBeSent = new File(input);
if (!toBeSent.exists()) {
input = cons.readLine("That file does not exist. Would you like to create it: \n");
if (input.equals("yes")) {
toBeSent.createNewFile();
System.out.println("File created, add something inside before sending");
continue;
}
}
else {
try {
dos.writeUTF(input);
dos.writeLong(toBeSent.length());
dos.flush();
InputStream is = new FileInputStream(toBeSent);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[4 * 1024];
int size = 0;
while ((size = bis.read(buffer)) > 0) {
dos.write(buffer, 0, size);
dos.flush();
}
bis.close();
is.close();
continue;
} catch (EOFException e) {
}
dos.close();
bos.close();
os.close();
}
}
This thing is, the server-side code
if (client.equals("close".trim().toLowerCase())) {
System.out.println("Client disconnected");
dis.close();
bis.close();
is.close();
exit = true;
continue;
}
works just fine, but only as the first input. As soon as the rest of the server code runs, it throws an exception whenever I try to input "close" from the client:
java.net.SocketException: Connection reset
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:313)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:340)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:789)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:1025)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:258)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:313)
at java.base/java.io.BufferedInputStream.implRead(BufferedInputStream.java:386)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:365)
at java.base/java.io.DataInputStream.read(DataInputStream.java:102)
at sg.edu.nus.iss.ClientHandler.run(ClientHandler.java:70)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1623)
The aforementioned Line 70 is the start of the while loop below:
while ((receivedBytes = dis.read(buffer)) > 0) {
bos.write(buffer, 0, receivedBytes);
remainingBytes = size - receivedBytes;
System.out.println(receivedBytes + " received...\n" + remainingBytes + "left");
bos.flush();
exit = true;
}
Any insight would be greatly appreciated. Thank you!