Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PrintWriter only sending part of string Java

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.

like image 642
Lolmewn Avatar asked Feb 28 '26 11:02

Lolmewn


1 Answers

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.

like image 124
Bernd Elkemann Avatar answered Mar 03 '26 00:03

Bernd Elkemann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!