Package

Source Code of TcpServer$TcpServerRunnable

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.*;

public class TcpServer {
    private Selector m_selector;
    private ServerSocketChannel m_channel;
    private Map<SocketChannel, TcpServerConnection> m_channelMap;
    private Thread m_thread;
    private TcpServerListener m_listener;
    private int m_port;
    private boolean m_close;

    public TcpServer(TcpServerListener listener, int port) {
        m_port = port;
        m_listener = listener;
        m_close = false;
    }

    class SocketChannelComparator implements Comparator<SocketChannel> {
        @Override
        public int compare(SocketChannel o1, SocketChannel o2) {
            return o1.hashCode() - o2.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            return (this == obj);
        }
    }

    class TcpServerRunnable implements Runnable {
        public void run() {
            try {
                m_selector = SelectorProvider.provider().openSelector();
                m_channel = ServerSocketChannel.open();
                InetSocketAddress addr = new InetSocketAddress(m_port);

                m_channel.configureBlocking(false);
                m_channel.socket().bind(addr);

                System.out.println("Running...");

                m_channel.register(m_selector, SelectionKey.OP_ACCEPT);
                m_channelMap = new IdentityHashMap<SocketChannel, TcpServerConnection>();
            } catch (IOException e) {
                e.printStackTrace();
            }

            Iterator<SelectionKey> iterator;

            try {
                while (true) {
                    if (m_close)
                        return;

                    m_selector.select();

                    iterator = m_selector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                        SelectionKey key = iterator.next();
                        iterator.remove();

                        if (!key.isValid()) {
                            continue;
                        }

                        if (key.isConnectable()) {
                            SocketChannel m_socket = (SocketChannel) key.channel();
                            if (m_socket.isConnectionPending()) {
                                m_socket.finishConnect();
                            }
                        }

                        if (key.isAcceptable()) {
                            ServerSocketChannel socket = (ServerSocketChannel) key.channel();
                            SocketChannel client = socket.accept();

                            client.configureBlocking(false);
                            client.register(m_selector, SelectionKey.OP_READ);
                            m_channelMap.put(client, m_listener.onNewConnection(client));
                        }

                        if (key.isReadable()) {
                            SocketChannel client = (SocketChannel) key.channel();
                            TcpServerConnection connection = m_channelMap.get(client);

                            try {
                                ByteBuffer data = ByteBuffer.allocate(client.socket().getReceiveBufferSize());
                                if (client.read(data) == -1) {
                                    continue;
                                }

                                if (connection != null) {
                                    data.flip();
                                    connection.onDataReceived(data);
                                }
                            } catch (IOException e) {
                                if (connection != null) {
                                    connection.onClosed();
                                    m_channelMap.remove(client);
                                }
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void runServer() {
        m_thread = new Thread(new TcpServerRunnable());
        m_thread.run();
    }

    public synchronized void closeServer() {
        m_close = true;
        try {
            m_channel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
TOP

Related Classes of TcpServer$TcpServerRunnable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.