I am trying to create a messaging system,but first I would like the code to be able to do the following:
- Client sends a string
- 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.
