Android Open Source - android_asyncsocket Tcp Server Client






From Project

Back to project page android_asyncsocket.

License

The source code is released under:

GNU Lesser General Public License

If you think the Android project android_asyncsocket listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.smorra.asyncsocket;
//  www  .  j a  v a2 s .co m
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

import android.os.Handler;
import android.os.Looper;

public class TcpServerClient extends Thread
{

  SocketChannel sc;
  Pipe p;
  boolean closed = false;
  TcpServerClientCallback tcc;
  BigInteger bytesWritten = BigInteger.ZERO;
  BigInteger bytesQueued = BigInteger.ZERO;

  public TcpServerClient(SocketChannel sc) throws IOException
  {
    this.sc = sc;
    p = Pipe.open();
    p.sink().configureBlocking(true);
    p.source().configureBlocking(false);
    start();
  }

  public int bytesInQueue()
  {
    return bytesQueued.subtract(bytesWritten).intValue();
  }

  public void setCallbackInterface(TcpServerClientCallback tcc)
  {
    this.tcc = tcc;
  }

  public void write(byte[] b) throws IOException
  {
    // System.out.println("writing to sink: " + b.length);
    p.sink().write(ByteBuffer.wrap(new byte[] { 0 }));
    ByteBuffer bb = ByteBuffer.allocate(4);
    bb.putInt(b.length);
    bb.rewind();
    p.sink().write(bb);
    p.sink().write(ByteBuffer.wrap(b));
    bytesQueued = bytesQueued.add(BigInteger.valueOf(b.length));
  }

  public void close() throws IOException
  {
    if (closed)
      throw new IOException("already closed");
    p.sink().write(ByteBuffer.wrap(new byte[] { 1 }));
    closed = true;
  }

  public boolean isClosed()
  {
    return closed;
  }

  public void run()
  {
    try
    {
      byte[] writeBuffer = new byte[0];
      byte[] readBuffer = new byte[0];
      boolean closed2 = false;
      while (!closed2)
      {
        Selector selector = Selector.open();
        sc.register(selector, SelectionKey.OP_READ);
        if (writeBuffer.length != 0)
          sc.register(selector, SelectionKey.OP_WRITE);
        p.source().register(selector, SelectionKey.OP_READ);
        selector.select();
        for (SelectionKey k : selector.selectedKeys())
        {
          // System.out.println("TcpServerClient select");

          if (k.channel() == sc && k.isReadable())
          {
            // System.out.println("IS READABL");
            ByteBuffer b = ByteBuffer.allocate(1024);

            int n = -1;
            try
            {
              n = sc.read(b);
            }
            catch (Exception e)
            {
            }
            // System.out.println("READ: " + n);
            if (n == -1)
            {
              sc.close();
              new Handler(Looper.getMainLooper()).post(new Runnable()
              {

                @Override
                public void run()
                {
                  if (!closed && tcc != null)
                  {
                    tcc.onDisconnect(TcpServerClient.this);
                  }
                }
              });
              return;
            }
            byte[] bytes = new byte[n];
            System.arraycopy(b.array(), 0, bytes, 0, n);
            final byte[] readBytes = bytes;
            new Handler(Looper.getMainLooper()).post(new Runnable()
            {

              @Override
              public void run()
              {
                if (!closed && tcc != null)
                {
                  tcc.onRead(TcpServerClient.this, readBytes);
                }
              }
            });

          }
          else if (k.channel() == sc && k.isWritable())
          {
            // System.out.println("IS WRITABL");
            final int n;
            try
            {
              n = sc.write(ByteBuffer.wrap(writeBuffer));
            }
            catch (Exception e)
            {
              sc.close();
              new Handler(Looper.getMainLooper()).post(new Runnable()
              {
                @Override
                public void run()
                {
                  if (!closed || tcc == null)
                    return;
                  tcc.onDisconnect(TcpServerClient.this);
                }
              });
              return;
            }
            byte[] newWriteBuffer = new byte[writeBuffer.length - n];
            System.arraycopy(writeBuffer, n, newWriteBuffer, 0, writeBuffer.length - n);
            writeBuffer = newWriteBuffer;
            if (writeBuffer.length == 0)
            {
              new Handler(Looper.getMainLooper()).post(new Runnable()
              {

                @Override
                public void run()
                {
                  bytesWritten = bytesWritten.add(BigInteger.valueOf(n));
                  if (!closed && bytesWritten.equals(bytesQueued))
                  {
                    tcc.onWritten(TcpServerClient.this);
                  }
                }
              });
            }
          }
          else if (k.channel() == p.source() && k.isReadable())
          {
            while (true)
            {
              ByteBuffer bb = ByteBuffer.allocate(1024);
              int n = p.source().read(bb);
              // System.out.println("Bytes read: " + n);
              byte[] readBuffer2 = new byte[readBuffer.length + n];
              System.arraycopy(readBuffer, 0, readBuffer2, 0, readBuffer.length);
              System.arraycopy(bb.array(), 0, readBuffer2, readBuffer.length, n);
              readBuffer = readBuffer2;

              if (n != bb.capacity())
                break;
            }
            // TODO READ MORE

            while (true)
            {
              // System.out.println("parsing command");
              if (readBuffer.length >= 5 && readBuffer[0] == 0)
              {
                byte[] length = new byte[] { readBuffer[1], readBuffer[2], readBuffer[3], readBuffer[4] };
                int ilength = ByteBuffer.wrap(length).getInt();
                // System.out.println("write command, " +
                // ilength);

                if (readBuffer.length >= 5 + ilength)
                {
                  // System.out.println("in if");
                  byte[] wdata = new byte[ilength];
                  System.arraycopy(readBuffer, 5, wdata, 0, ilength);

                  byte[] writeBufferNew = new byte[writeBuffer.length + wdata.length];
                  System.arraycopy(writeBuffer, 0, writeBufferNew, 0, writeBuffer.length);
                  System.arraycopy(wdata, 0, writeBufferNew, writeBuffer.length, ilength);
                  writeBuffer = writeBufferNew;

                  byte[] readBufferNew = new byte[readBuffer.length - 5 - ilength];
                  System.arraycopy(readBuffer, 5 + ilength, readBufferNew, 0, readBuffer.length - 5 - ilength);
                  readBuffer = readBufferNew;
                }
                else
                {
                  // System.out.println("Aborting parsing command. file is not here completely");
                  break;
                }
              }
              else if (readBuffer.length >= 1 && readBuffer[0] == 1)
              { // close
                // System.out.println("close command");
                sc.close();
                return;
              }
              else
              { // no more commands
                // System.out.println("no more commands");
                break;
              }
            }
          }
        }
        selector.close();
      }
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
}




Java Source Code List

com.smorra.asyncsocket.DnsResolverCallback.java
com.smorra.asyncsocket.DnsResolver.java
com.smorra.asyncsocket.SSLClientCallback.java
com.smorra.asyncsocket.SSLClient.java
com.smorra.asyncsocket.TcpClientCallback.java
com.smorra.asyncsocket.TcpClient.java
com.smorra.asyncsocket.TcpServerCallback.java
com.smorra.asyncsocket.TcpServerClientCallback.java
com.smorra.asyncsocket.TcpServerClient.java
com.smorra.asyncsocket.TcpServer.java