I'm doing some socket work in Java, and am trying to encode the data it is sending. That part is working correctly, but for some reason it doesn't send the whole encoded String over the socket. It seems to send it in parts of 3.
The client performs a simple readLine() from the MyBufferedReader class (which is below), and the server sends it like this:
private void sendFile(File f, String dest){ //The file to be sent and the destination
System.out.println("Sending file started..");
try {
this.out.println("CMD MKFILE " + dest + "/" + f.getName());
//TODO send the file
}catch(Exception e){
e.printStackTrace();
}
}
The client receives this:
CMD MKFILE C:\Users\Lolmewn\Documents\test/dir/n/linebrea and after another read k!.txt
The MyBufferedReader and MyPrintWriter classes look like this:
MyBufferedReader:
@Override
public String readLine() throws IOException {
String read = super.readLine();
System.out.println("UNDEC: " + read);
try {
System.out.println("DEC: " + decode(read));
return decode(read);
} catch (Exception e) {
e.printStackTrace();
}
return read;
}
public static String decode(String b) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(b.getBytes("UTF-8"));
InputStream b64is = MimeUtility.decode(bais, "base64");
byte[] tmp = new byte[b.length()];
int n = b64is.read(tmp);
byte[] res = new byte[n];
System.arraycopy(tmp, 0, res, 0, n);
return new String(res);
}
and MyPrintWriter:
private String hash(String x) {
try {
return encode(x);
} catch (Exception e) {
e.printStackTrace();
}
return x;
}
public static String encode(String b) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream b64os = MimeUtility.encode(baos, "base64");
b64os.write(b.getBytes("UTF-8"));
b64os.close();
return new String(baos.toByteArray());
}
What's happening and how can I fix this?
Please do note: I am doing async work on these Sockets, meaning I can't just use a while(read != null) statement. That would cause other data not supposed to be there being there too.
First this aside: If you are sending from multiple threads/clients then you should open one socket for each of them (like accept() does), that way messages from different clients cannot interleave one another.
Now i am assuming only a single client per socket (reasonable):
I can't just use a while(read != null)
You have to implement a simple protocol with which you can distinguish one message from the next, e.g. use a 0-byte if that can never be part of the data or prefix the message with the length of the message and send both; that way your server can distinguish one message from the next.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With