title: Netty Client to Server message
body: <p>This is actually my first post on here and I have been trying to figure this out for some time but I am finally calling in the flag and going to try to get some help on this topic.</p>
  
  <p>So I have a Client and a Server that was modeled after the echo client/server and the secure chat client/server. I am not interested in the SSL part of the chat and using the echo just to ensure that I am getting responses to and from the client/server. I will add all the pertinent code at the bottom of this post. The problem I am getting at the moment is that I can send a message from the server to the client upon the client connecting but I am not able to send a message from the client to the Server upon the server sending the client the initial message. The message being sent from the server is:</p>
  
  <pre><code>Welcome to the server!
  </code></pre>
  
  <p>The message from the client is </p>
  
  <pre><code>test
  </code></pre>
  
  <p>I should know that I got the message from the client cause it should echo back </p>
  
  <pre><code>[You] test
  </code></pre>
  
  <p>I do know that the Server sees the Client and it gives me status updates but I cannot send a message to the server for some reason. Now for a question on top of this... By some chance I am currently using a <i>StringDecoder</i> and <i>StringEncoder</i> as the Decoder and Encoder... If you are making a game (which is what I am doing) and you will have things like logins, player movements, world updates, etc... is sending Strings the best way to do this? I know I see a lot with byte streams and in my programming class I went through we touched on manipulating byte streams but I am still not 100% comfortable with them yet. If byte streams are the better/best way to do this then can someone please explain in some detail how it works to manipulate a byte stream to be able to handle different items.</p>
  
  <p>As stated before this is the start of everything in the client:</p>
  
  <pre><code>public class Client {
  
  public Client() {
      // Initialize the window
      GameWindow.init();
      // Initialize the server connection
      ClientHandler.init();
  }
  
  public static void main(String[] args) throws Exception {
  
      // Set a default server address if one isn't specified in the arguments
      if (args.length &lt; 2 || args.length &gt; 3) {
          System.err.println("Usage: " + Client.class.getSimpleName() + " &lt;host&gt; &lt;port&gt; [&lt;first message size&gt;]");
          System.err.println("Using default values.");
      } else {
          // Parse arguments
          Settings.host = args[0];
          Settings.port = Integer.parseInt(args[1]);
      }
  
      // start client
      new Client();
  }
  </code></pre>
  
  <p>ClientHandler:</p>
  
  <pre><code>package simple.client.net;
  
  import java.net.InetSocketAddress;
  import java.util.concurrent.Executors;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  
  import org.jboss.netty.bootstrap.ClientBootstrap;
  import org.jboss.netty.channel.Channel;
  import org.jboss.netty.channel.ChannelFuture;
  import org.jboss.netty.channel.ChannelHandlerContext;
  import org.jboss.netty.channel.ChannelStateEvent;
  import org.jboss.netty.channel.ExceptionEvent;
  import org.jboss.netty.channel.MessageEvent;
  import org.jboss.netty.channel.SimpleChannelHandler;
  import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
  import org.jboss.netty.channel.WriteCompletionEvent;
  import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
  
  import simple.client.Settings;
  
  public class ClientHandler extends SimpleChannelUpstreamHandler {
  
  private static final Logger logger = Logger.getLogger(ClientHandler.class.getName());
  
  public static Channel channel;
  
  public ClientHandler() {
  }
  
  public static void init() {
      // Configure the client.
      ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
  
      // Set up the pipeline factory.
      bootstrap.setPipelineFactory(new ClientPipelineFactory());
  
      // Start the connection attempt.
      ChannelFuture future = bootstrap.connect(new InetSocketAddress(Settings.host, Settings.port));
  
      // Wait until the connection is closed or the connection attempt fails.
      channel = future.awaitUninterruptibly().getChannel();
  
      // This is where the test write is &lt;&lt;------
      ChannelFuture test = channel.write("test");
  
      if (!future.isSuccess()) {
          future.getCause().printStackTrace();
          bootstrap.releaseExternalResources();
          return;
      }
  }
  
  @Override
  public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Bound: " + e.getChannel().isBound());
  }
  
  @Override
  public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Connected: " + e.getChannel().isConnected());
      System.out.println("Connected: " + e.getChannel().getRemoteAddress());
  }
  
  @Override
  public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Closed: " + e.getChannel());
  }
  
  @Override
  public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Disconnected: " + e.getChannel());
  }
  
  @Override
  public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Open: " + e.getChannel().isOpen());
  }
  
  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
      System.out.println("Error: " + e.getCause());
  }
  
  @Override
  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
      System.out.println("Message: " + e.getMessage());
  }
  }
  </code></pre>
  
  <p>And finally the ClientPipeline:</p>
  
  <pre><code>package simple.client.net;
  
  import static org.jboss.netty.channel.Channels.*;
  import org.jboss.netty.channel.ChannelPipeline;
  import org.jboss.netty.channel.ChannelPipelineFactory;
  import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
  import org.jboss.netty.handler.codec.frame.Delimiters;
  import org.jboss.netty.handler.codec.string.StringDecoder;
  import org.jboss.netty.handler.codec.string.StringEncoder;
  
  public class ClientPipelineFactory implements ChannelPipelineFactory {
  
  public ChannelPipeline getPipeline() throws Exception {
      ChannelPipeline pipeline = pipeline();
  
      pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
      pipeline.addLast("decoder", new StringDecoder());
      pipeline.addLast("encoder", new StringEncoder());
      pipeline.addLast("handler", new ClientHandler());
  
      return pipeline;
  }
  
  }
  </code></pre>
  
  <p>Server Side:</p>
  
  <pre><code>package simple.server;
  
  public class Server {
  public static void main(String[] args) throws Exception {
      ServerChannelHandler.init();
  }
  }
  </code></pre>
  
  <p>ServerChannelHandler:</p>
  
  <pre><code>package simple.server;
  
  import java.net.InetSocketAddress;
  import java.util.concurrent.Executors;
  import java.util.logging.Logger;
  
  import org.jboss.netty.bootstrap.ServerBootstrap;
  import org.jboss.netty.buffer.ChannelBuffer;
  import org.jboss.netty.channel.Channel;
  import org.jboss.netty.channel.ChannelHandlerContext;
  import org.jboss.netty.channel.ChannelStateEvent;
  import org.jboss.netty.channel.Channels;
  import org.jboss.netty.channel.ExceptionEvent;
  import org.jboss.netty.channel.MessageEvent;
  import org.jboss.netty.channel.SimpleChannelHandler;
  import org.jboss.netty.channel.group.ChannelGroup;
  import org.jboss.netty.channel.group.DefaultChannelGroup;
  import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
  
  public class ServerChannelHandler extends SimpleChannelHandler {
  
  private static final Logger logger = Logger.getLogger(ServerChannelHandler.class.getName());
  
  private static ChannelGroup channels;
  private static ServerBootstrap bootstrap;
  
  public ServerChannelHandler() {
  }
  
  /**
   * Initialize the Server Channel Handler
   */
  public static void init() {
      // create a channels group to add incoming channels to
      channels = new DefaultChannelGroup();
  
      // create the server bootstrap (fancy word for pre-made server setup)
      bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
              Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
  
      // set the server pipeline factory
      bootstrap.setPipelineFactory(new ServerPipelineFactory());
  
      // server settings
      bootstrap.setOption("keepAlive", true);
  
      // bind the server to the port
      bootstrap.bind(new InetSocketAddress(Settings.PORT_ID));
  }
  
  @Override
  public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Bound: " + e.getChannel());
  }
  
  @Override
  public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Connected: " + e.getChannel());
      channels.add(e.getChannel());
      e.getChannel().write("Welcome to the test server!\n\r");
  }
  
  @Override
  public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Closed: " + e.getChannel());
  }
  
  @Override
  public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Disconnected: " + e.getChannel());
  }
  
  @Override
  public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {
      System.out.println("Open: " + e.getChannel());
  }
  
  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
      System.out.println("Error: " + e.getCause());
  }
  
  @Override
  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
      System.out.println("Message: " + e.getMessage());
      for (Channel c : channels) {
          if (e.getMessage().equals("shutdown")) {
              shutdown();
          }
          if (c != e.getChannel()) {
              c.write("[" + e.getChannel().getRemoteAddress() + "] " + e.getMessage() + "\n\r");
          } else {
              c.write("[You] " + e.getMessage() + "\n\r");
          }
      }
  }
  
  /**
   * Shuts down the server safely
   */
  public static final void shutdown() {
      channels.close();
      bootstrap.releaseExternalResources();
      System.exit(0);
  }
  }
  </code></pre>
  
  <p>ServerPipelineFactory:</p>
  
  <pre><code>package simple.server;
  
  import org.jboss.netty.channel.ChannelPipeline;
  import org.jboss.netty.channel.ChannelPipelineFactory;
  import org.jboss.netty.channel.Channels;
  import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
  import org.jboss.netty.handler.codec.frame.Delimiters;
  import org.jboss.netty.handler.codec.string.StringDecoder;
  import org.jboss.netty.handler.codec.string.StringEncoder;
  
  import simple.server.decoder.Decoder;
  import simple.server.encoder.Encoder;
  
  public class ServerPipelineFactory implements ChannelPipelineFactory {
  @Override
  public ChannelPipeline getPipeline() throws Exception {
      ChannelPipeline pipeline = Channels.pipeline();
  
      pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
      pipeline.addLast("decoder", new StringDecoder());
      pipeline.addLast("encoder", new StringEncoder());
      pipeline.addLast("handler", new ServerChannelHandler());
  
      return pipeline;
  }
  }
  </code></pre>
  
  <p>Once again everyone I appreciate any help you can give me on understanding this.</p>