Back to project page android_asyncsocket.
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.
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(); } } }