Non-Netty client - Any help please, nearly there!

skhalid shahbaz.khalid at gmail.com
Sat Dec 27 14:50:30 EST 2008


NOTE: I am using a simple NIO client, and not using netty at all in my
client.

I've tried this on my own, and things are working better than before - I've
adapted the Telnet example in netty to send/receive my custom objects
instead of strings. I've used Compatible versions of the object
encoder/decoder. The problem is that the client can get the initial object
from when it connects to the server e.g. from 'channelConnected' and
deserialise it, the client can then send an object to the server. Well, the
object is sent successfully, and in the messageReceived method, it is
decoded properly. But when it responds to the client, the encoding is very
strange, and it only encodes/serialises the data that is INSIDE my object.
Lets say my Message object had an int and string - it would not send the
class name/header as part of the serialised bytes, but only encodes the int
and string data. In my own NIO client, I am deserialising and serialising
the bytes into objects manually 
(http://www.jguru.com/faq/view.jsp?EID=103437).

So here is what is happening in the following steps

1. Client connects
2. Server's channelConnected() method is called, and it sends 'Message'
object back to the client - it is properly encoded, and the unserialised
into an object at client side from bytes.
3. The client sends a Message with an empty string, by serialising it and
converting into bytes.
4. The server receives it in the messageReceived() method, and decodes is
successfully.
5. The server then creates a new object and tries to send it back to the
client (the same compatible encoder is called which was called during the
channelConnected method.
6. The client receives the bytes, tries to deserialise the object, and gets
Exception in thread "main" java.io.StreamCorruptedException: invalid stream
header  error. 

If I try to send something as simple as a String, it ONLY sends the
characters inside the string, and not the serialised data for String.


I don't know what the problem is - but it looks as if that for
channelConnected, the encoder works properly, but for messageReceived, it's
acting a bit strange.



Here are the changes:

TelnetPipelineFactory.java:

//changed the following code
/*pipeline.addLast("framer", new DelimiterBasedFrameDecoder(
                8192, Delimiters.lineDelimiter()));*/
        pipeline.addLast("encoder", new CompatibleObjectDecoder());
        pipeline.addLast("decoder", new CompatibleObjectEncoder());



TelnetServerHandler.java:

    public void channelConnected(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception
{
        // Send greeting for a new connection.
    	Message m = new Message();
    	m.s = new String("Welcome to " +
InetAddress.getLocalHost().getHostName() + "!");
        e.getChannel().write(m);
    }


    public void messageReceived(
            ChannelHandlerContext ctx, MessageEvent e) {
        Message request = (Message) e.getMessage();

        // Generate and write a response.
        String response;
        boolean close = false;
        if (request.s.length() == 0) {
            response = "Please say something";
        } else if (request.s.toLowerCase().equals("bye")) {
            response = "Have a good day!";
            close = true;
        } else {        	
            response = "Did you say '" + request.s + "'?";
        }

        Message m = new Message();
        m.s = response;
        

        // We do not need to write a ChannelBuffer here.
        // We know the encoder inserted at TelnetPipelineFactory will do the
conversion.
              
        ChannelFuture future = e.getChannel().write(buf.array());

        // Close the connection after sending 'Have a good day!'
        // if the client has sent 'bye'.
        if (close) {
            future.addListener(ChannelFutureListener.CLOSE);
        }
    }


Message is just a wrapper for a String.

For my client, I am using this code:

		int servPort = 8181;

		// Create channel and set to nonblocking
		SocketChannel clntChan = SocketChannel.open();
		clntChan.configureBlocking(false);

		// Initiate connection to server and repeatedly poll until complete
		if (!clntChan.connect(new InetSocketAddress("localhost", servPort))) {
			while (!clntChan.finishConnect()) {
				System.out.print("."); // Do something else
			}
		}
		System.out.print("Connected.");

                // try to get welcome message object
		ByteBuffer readBuf = ByteBuffer.allocate(1000);
		int totalBytesRcvd = 0; // Total bytes received so far
		int bytesRcvd; // Bytes received in last read
		while (totalBytesRcvd < 300) {
			if ((bytesRcvd = clntChan.read(readBuf)) == -1) {
				//throw new SocketException("Connection closed prematurely");
				break;
			}
			totalBytesRcvd += bytesRcvd;
			Thread.currentThread().sleep(500);
		}

		System.out.println("Total Bytes Received are: " + totalBytesRcvd);
		
		
		byte [] ary = readBuf.array();
		
				
        ByteArrayInputStream bais = new ByteArrayInputStream(ary);
        ObjectInputStream ois = new ObjectInputStream(bais);
        Message m = null;
        try {
			Object myObject = ois.readObject();
			m = (Message)myObject;
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("Server said in bytes: " + new String(ary));
		System.out.println("Server said: " + m.s);
		
		
		
		System.out.println("Sending empty string to server");
		ByteBuffer buf = null;
		
		m = new Message();
		m.s = new String("");
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);    
        oos.writeObject(m);
        buf = ByteBuffer.wrap(baos.toByteArray());
		
        System.out.println("Sending " + buf.array().length + " bytes to
server");
        
        clntChan.write(buf);
        
        // Now read response from server
        readBuf = ByteBuffer.allocate(1000);
        
        totalBytesRcvd = 0;
        bytesRcvd = 0;
		while (totalBytesRcvd < 100) {
			if ((bytesRcvd = clntChan.read(readBuf)) == -1) {
				//throw new SocketException("Connection closed prematurely");
				break;
			}
			totalBytesRcvd += bytesRcvd;
			Thread.currentThread().sleep(500);
		}
		
		ary = readBuf.array();

		System.out.println("Total Bytes Received are: " + totalBytesRcvd);
		String s = new String(ary);
		
		System.out.println("Server said in bytes: " + s);
		
		
        bais = new ByteArrayInputStream(ary);
        ois = new ObjectInputStream(bais);   // here is where it fails.

        try {
			Object myObject = ois.readObject();
			System.out.println("Object of class is " +
myObject.getClass().toString());
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

-- 
View this message in context: http://n2.nabble.com/Non-Netty-client-tp1771503p2016631.html
Sent from the Netty User Group mailing list archive at Nabble.com.




More information about the netty-users mailing list