tags:

views:

63

answers:

2

Dear All,

Here One server and one client is there. And communication has been maintained by selectable Channel. like-- Server ---

  SelectionKey selectKey = channel.register(this.selector,

        SelectionKey.OP_ACCEPT);

while (selectKey.selector().select() > 0) {

    Set<SelectionKey> selectedKeys = this.selector.selectedKeys();

    Iterator<SelectionKey> iterator = selectedKeys.iterator();

    while (iterator.hasNext()) {

        SelectionKey key = iterator.next();

        iterator.remove();

        if (key.isAcceptable()) {

            ServerSocketChannel nextChannel = (ServerSocketChannel) key

                        .channel();
            SocketChannel newChannel = nextChannel.accept();

            newChannel.configureBlocking(false);

            if (!newChannel.isRegistered()) {

                SelectionKey selectionKey = newChannel.register(

                     this.selector, SelectionKey.OP_READ

                | SelectionKey.OP_WRITE);

                selectionKey.attach(newChannel);

            }

        } else if (key.isWritable()) {

             SocketChannel attachment1 = (SocketChannel)key.attachment();
             ByteBuffer writeBuffer = ByteBuffer.wrap("Hello".getBytes());

                attachment1.write(writeBuffer);

                System.out.print("Written");
            }
         }
      } 

Client :

   InetSocketAddress isa = new InetSocketAddress(InetAddress
            .getLocalHost(), 4444);
    SocketChannel sc = null;

    try {

        while (true) {

            Thread.sleep(10000);
            sc = SocketChannel.open();
            sc.connect(isa);
            ByteBuffer byteBuffer = ByteBuffer.allocate(BUFSIZE);
            int nbytes = sc.read(byteBuffer);
            byteBuffer.flip();
            dbuf.flip();
            CharBuffer cb = decoder.decode(byteBuffer);
            System.out.println(isa + " : " + cb);

        }

The Problem is that every time client read the data up to full size of buffer limit of client instead of sent data limit.

Kindly Help me regarding this issue.

Thanks-- Subhrajyoti Majumder

+4  A: 

This is the way TCP sockets work -- they are a stream of bytes, not a sequence of messages.

You'll need to design in a higher level protocol so that the receiver can re-discover the message boundaries after it receives the bytes.

Darron
Just a nitpick - this is the way TCP sockets work.
Nikolai N Fetissov
Indeed. UDP will deliver "messages" just fine. I forget whether SCTP does the same, or whether Java supports it for that matter.
cHao
Hello Darron,Can you help me to design protocol by that I can set up boundary ?even before sending buffer data form server side i flipped the buffer which set the position.Its not working.
Subhrajyoti Majumder
I Fixed the TCP/UDP thing.
Darron
@Subhrajyoti -- your protocol will have to be something in the bytes you send. Either a message length or special marker bytes. Whatever it is must carry sufficient information for the receiver to find message boundaries.
Darron
+1  A: 

There are some very strange things in your code. No wonder it is misbehaving.

  1. A channel accepted from a ServerSocketChannel is brand new, so checking whether it's registered or not is a waste of time. It isn't registered.

  2. Attaching the channel to the selection key is pointless: SelectionKey already has a channel() method. The attachment should be some kind of session context object containing the buffers for the session and any other state you need to keep.

  3. Your server never reads from any channel. So it can't detect orderly disconnections, so it never closes a channel, so it has to keep dealing with every channel it has ever accepted.

  4. Your server doesn't check the result of write(). It can be anything from zero to buffer.remaining().

  5. Allocating a new ByteBuffer per read is extremely wasteful. They are relatively expensive to create. You should create one per channel and use it for the life of the channel. Maybe two, one for reading and one for writing.

  6. You are never closing the SocketChannel in the client, so you will overwhelm the server with idle connections.

  7. You are misusing OP_WRITE. OP_WRITE is ready all the time except when the socket's send buffer is full. You should (a) just write when you are ready, (b) check the return value, (c) register the channel for OP_WRITE if it is zero, (d) when you get OP_WRITE, do a write, and deregister OP_WRITE unless you got another zero. At present you are also overwhelming the server by making it write to every channel, and you aren't even reading all those writes with your client.

  8. After the flip()/decode() sequence you must compact() the buffer if it's going to be re-used, as it should be.

EJP