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.