I've written a client-server combo using sockets, and the client seems to continuallly get stuck on a particular loop, after receiving a file.
The server sends a file, and then 3 strings once the file transfer is complete (which each are preceded by a byte "1". The receives the file successfully, and then continually gets stuck on the following loop:
while (instruction == 0) {
instruction = in.readByte();
sentString = new byte[in.readShort()];
in.read(sentString);
message.concat(new String(sentString, "UTF-8"));
}
After stepping through it, I have noticed that it continually reads the zero followed by an empty string, but while stepping through the server and continually setting break points, I have observed that it never (in this example) sends 0, so why does the client keep receiving it?
I have included all the code for both classes below. Any help would be greatly appreciated.
The complete server code is:
import java.net.*;
import java.io.*;
public class WebServer
{
private File file;
private Socket client = null;
private DataOutputStream terminal;
private byte info;
//The above byte contains the two information bits of the protocol.
//The second bit is the type of transfer, and the first bit is whether
//the transfer is complete or not. So, b00 == 0 == "Message transfer, not complete."
//b01 == 1 == "Message Transfer, complete.", b10 == 2 == "File transfer, not complete.",
//and b11 == 3 == "File Transfer, complete."
private byte sendBuffer[];
private short size;
public static void main(String[] args) throws IOException {
WebServer webServer = new WebServer();
}
public WebServer() throws IOException {
ServerSocket server = null;
try {
server = new ServerSocket(8008);
} catch (IOException e) {
System.out.println("Unable to listen to Port 8008.");
System.exit(1);
}
try {
client = server.accept();
} catch (IOException e) {
System.err.println("Connection failed.");
System.exit(1);
}
sendBuffer = new byte[client.getReceiveBufferSize()];
terminal = new DataOutputStream(client.getOutputStream());
BufferedReader command = new BufferedReader(new InputStreamReader(client.getInputStream()));
writeMessage("Welcome to Jimmy's webserver.\n", false);
String input;
while ((input = command.readLine()) != null) {
if (input.toLowerCase().equals("exit")) {
break;
}
else if (input.toLowerCase().equals("help")) {
writeMessage("Commands:\n", false);
writeMessage("GET <filename> - JWS will send <filename> to you.\n", false);
writeMessage("EXIT - exits Jimmy's Webserver.\n", false);
}
else if (input.toLowerCase().startsWith("get ")) {
sendFile(new File(input.substring(4)));
}
}
terminal.close();
command.close();
client.close();
server.close();
}
private void sendFile(File file) throws FileNotFoundException, IOException {
if (file == null) {
writeMessage("Please use the command: GET filename\n", false);
}
else if (!file.exists()) {
writeMessage(file.toString() + " could not be found in the current directory.\n", false);
}
else {
writeMessage("Sending file: " + file.toString() + "\n", false);
writeMessage("File size: " + file.length() + "bytes.\n", false);
Long time = System.currentTimeMillis();
//message type: String or File (1 bit)
//transmission complete: (1 bit)
//sent size: 2 bytes
//
FileInputStream fileReader = new FileInputStream(file);
writeMessage(file.toString(), true);
long fileRemaining = file.length();
while (fileRemaining != 0) {
size = (short) fileReader.read(sendBuffer);
if (file.length() < sendBuffer.length) {
size = (short)file.length();
terminal.write(3);
}
else {
terminal.write(2);
}
terminal.writeChar(size);
fileReader.read(sendBuffer);
terminal.write(sendBuffer);
fileRemaining -= size;
}
fileReader.close();
writeMessage("Transfer of " + file.toString() + " is complete.\n", false);
time = System.currentTimeMillis() - time;
if (time == 0) { time++; }
writeMessage("Transfer took: " + time + " milliseconds.\n", false);
}
}
private void writeMessage(String s, boolean sendingFile) throws UnsupportedEncodingException, IOException { //replace these with try/catch.
byte stringBytes[] = s.getBytes("UTF-8");
if (sendBuffer.length > stringBytes.length) {
if (!sendingFile) {
terminal.write(1);
}
else {
terminal.write(2);
}
size = (short)stringBytes.length;
terminal.writeChar(size);
terminal.write(stringBytes);
}
else {
terminal.write(0);
size = (short)sendBuffer.length;
long sent = 0;
terminal.writeChar(size);
while (sent < (stringBytes.length - sendBuffer.length)) {
terminal.write(0);
terminal.writeChar(size);
for (int i = 0; i < sendBuffer.length; i++, sent++) {
sendBuffer[i] = stringBytes[(int)sent];
}
terminal.write(sendBuffer);
}
terminal.write(1);
size = (short)(stringBytes.length - sendBuffer.length);
terminal.writeChar(size);
for (int i = 0; i < size; i++) {
sendBuffer[i] = stringBytes[i + (int)sent]; //try and find out why these sents need casting to ints?
}
terminal.write(sendBuffer);
}
}
}