0

I am trying to create a messaging system,but first I would like the code to be able to do the following:

  1. Client sends a string
    1. Server receives the string and echos it back to the client that sent it

For some reason this is what happens

Client : Sent String : meow
Server : Received : [B@5ef4b65d
Client : Received : [B@5ef4b65d

what does [B@5ef4b65d mean? Does it mean that the client is not able to send meow to server and the server just generates some random string? I am not able to figure out what going on. I have pasted my code, but if someone can let me know what this means, I can probably take it from there.

ClientCore:

    public void send(byte[] data, ResponseHandler handler) throws IOException {
        byte[] rspData = "ERROR".getBytes(); 

        try {

            ByteBuffer sendStr = ByteBuffer.wrap(data);
            ByteBuffer rcv = ByteBuffer.allocateDirect(BUFFER_SIZE);

            channel.write(sendStr).get();
            // By adding .get(), this becomes a blocking call.
            int numRead = channel.read(rcv).get();

            rcv.flip();

            String rspStr = Charset.defaultCharset().decode(rcv).toString();
            //String dummyresp = ByteBuffer.wrap(rcv).getString();
            rspData = rspStr.getBytes();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } finally {
        }

        handler.handleResponse(rspData);
    }

}

ResponseHandler:

public class ResponseHandler {
    private byte[] rsp = null;

    public synchronized boolean handleResponse(byte[] rsp) {
        this.rsp = rsp;
        this.notify();
        return true;
    }

    public synchronized byte[] waitForResponse() {
        while (this.rsp == null) {
            try {
                this.wait();
                // interrupt thread
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //String response = new String(this.rsp);
        return this.rsp;
    }
}

Server :

    public void read(SelectionKey key) throws IOException {



        SocketChannel socketChannel = (SocketChannel) key.channel();

        // Clear out our read buffer so it's ready for new data
        this.readBuffer.clear();

        // Attempt to read off the channel
        int numRead;
        try {
            numRead = socketChannel.read(this.readBuffer);
        } catch (IOException e) {
            // The remote forcibly closed the connection, cancel
            // the selection key and close the channel.
            key.cancel();
            socketChannel.close();
            return;
        }
        // numread is the number of bytes in the buffer
        if (numRead == -1) {
            // Remote entity shut the socket down cleanly. Do the
            // same from our end and cancel the channel.
            key.channel().close();
            key.cancel();
            return;
        }

        // Hand the data off to the Message Worker
        System.out.println(readBuffer.array());
        messageWorkerPool.execute(new MessageWorker(this, socketChannel,this.readBuffer.array(), numRead, 0));

    }

    public void write(SelectionKey key) throws IOException {

        SocketChannel socketChannel = (SocketChannel) key.channel();

        synchronized (this.pendingData) {
            List<ByteBuffer> queue = this.pendingData.get(socketChannel);

            // Write until there's not more data ...
            while (!queue.isEmpty()) {
                ByteBuffer buf = (ByteBuffer) queue.get(0);
                socketChannel.write(buf);
                if (buf.remaining() > 0) {
                    // ... or the socket's buffer fills up
                    break;
                }
                queue.remove(0);
            }

            if (queue.isEmpty()) {
                // We wrote away all data, so we're no longer interested
                // in writing on this socket. Switch back to waiting for
                // data.
                key.interestOps(SelectionKey.OP_READ);
            }
        }



    }

    public void send(SocketChannel socket, byte[] data) {
        synchronized (this.pendingChanges) {
            // Indicate we want the interest ops set changed


            long changeQueueArrivalTime = System.currentTimeMillis();
            this.pendingChanges.add(new ChangeRequest(socket,
                    ChangeRequest.CHANGEOPS, SelectionKey.OP_WRITE,
                    changeQueueArrivalTime));
            // And queue the data we want written
            synchronized (this.pendingData) {
                List<ByteBuffer> queue = this.pendingData.get(socket);
                if (queue == null) {
                    queue = new ArrayList<ByteBuffer>();
                    this.pendingData.put(socket, queue);
                }
                queue.add(ByteBuffer.wrap(data));
            }
        }

        // Finally, wake up our selecting thread so it can make the required
        // changes
        this.selector.wakeup();
    }

From its main I call

ExecutorService servicePool = Executors
            .newFixedThreadPool(2);
    servicePool.execute(new MessageServer(servicePool,"localhost", 4444, 200));

and the worker :

public class MessageWorker implements Runnable {
    MessageServer server;
    SocketChannel socketchannel;

    int bufferlength;
    int begin_wait_worker;
    ServerDataEvent dataevent;
    String end;

    // will add pgpooling soon
    public MessageWorker(MessageServer server,SocketChannel sc, byte[] bs,int bufferlength, int start_wait_for_begin){
        end = "???";
        this.server = server;
        this.socketchannel = sc;

        this.bufferlength = bufferlength;
        this.begin_wait_worker =start_wait_for_begin; //just the time when the server wait for worker to start working on the read request
        byte[] dataCopy = new byte[bufferlength];
        System.arraycopy(bs, 0, dataCopy, 0, this.bufferlength);
        // used to send easily
        this.dataevent = new ServerDataEvent(this.server,this.socketchannel,dataCopy);
    }

    public void run(){

        String request = dataevent.data.toString();
        String response = String.format(request, end); // all repsonse request end with ???

        // get request split conveniently
        //Map< MapParameters, String> commandparameters = MessageDecoder.decodeCommandToMap(request) ;
        }

        this.dataevent.server.send(dataevent.socket, response.getBytes());

        }
        }

EDIT : I tried converting to a string using the answer marked, I still get the same thing.

LoveMeow
  • 3,858
  • 9
  • 44
  • 66
  • I already tried converting it to string,I still get the same thing, could you possible show how its done? – LoveMeow Oct 02 '15 at 15:36
  • 1
    It's not done by calling `toString` on a `byte[]` which I assume is what `data` is. See the linked post. – Sotirios Delimanolis Oct 02 '15 at 15:38
  • Here's why you have that output: http://stackoverflow.com/questions/4479683/java-arrays-printing-out-weird-numbers-and-text – Sotirios Delimanolis Oct 02 '15 at 15:39
  • I understand now that I am not formatting it right, but I dont understand from these answers how I can get the right output – LoveMeow Oct 02 '15 at 15:44
  • Use the `String` constructor that accepts a `byte[]`. – Sotirios Delimanolis Oct 02 '15 at 15:48
  • I did String res = new String(handler.waitforresponse()); I get the same thing! – LoveMeow Oct 02 '15 at 15:50
  • I don't know what `handleresponse` is. Either it returns a `String` that contains the content you see, or it contains a `byte[]` whose value interpreted as a `String` is what you see. If you have a `byte[]` and you want to interpret its contents as a `String`, use the `String` constructor which accepts a `byte[]`. – Sotirios Delimanolis Oct 02 '15 at 15:52
  • That's a heck load of code, maybe you should isolate it. Secondly, that's when you are trying to toString a byte[], you get such stuff. – We are Borg Oct 02 '15 at 15:54
  • reponse handler returns a byte[] array, I did what you said and I dont understand why this happens,which is why I posted the question. I did not get my answer from the one you marked as duplicate. – LoveMeow Oct 02 '15 at 15:54
  • @WeareBorg I tried with without tostring, I tried string constructor and I still get the same thing. May be I am misinterpreting what I shud do. – LoveMeow Oct 02 '15 at 15:56
  • Meow, you should put less code...start with that. – We are Borg Oct 02 '15 at 15:58
  • Is your server echoing back what your client is sending? If you do the decoding wrong on the server, the echo back to client will also be wrong. Make sure it's correct in all places. – Sotirios Delimanolis Oct 02 '15 at 16:05
  • after I send data to the server, as you see I immediately printout what i get,what I concluded is that those odd symbols r what is received by the server itself,hence I ask for help, because I cannot locate the error. – LoveMeow Oct 02 '15 at 16:22
  • @SotiriosDelimanolis I found the error, basically when I do message.getBytes() that gets sent to the server, the server sends the message.getBytes() back, but after that whatever I seem to do,I cannot get back my original String. – LoveMeow Oct 02 '15 at 16:47
  • 2
    On what seems to be the server, you're doing `System.out.println(readBuffer.array());`. `println` internally invokes `toString` on the argument. That's not how you convert a `byte[]` to a `String`. I don't know what `ServerDataEvent` is, but you're probably doing the same thing then sending it to the client. – Sotirios Delimanolis Oct 02 '15 at 16:55
  • @SotiriosDelimanolis Your right! I was calling .toString() in the worker of the server, thank you!!!! – LoveMeow Oct 02 '15 at 17:09

0 Answers0