Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package server.network.nio;
- import java.io.IOException;
- import java.net.InetAddress;
- import java.net.InetSocketAddress;
- import java.net.NetworkInterface;
- import java.net.ServerSocket;
- import java.net.SocketException;
- import java.net.UnknownHostException;
- import java.nio.ByteBuffer;
- import java.nio.channels.ClosedChannelException;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.ServerSocketChannel;
- import java.nio.channels.SocketChannel;
- import java.util.ArrayList;
- import java.util.Enumeration;
- import java.util.Iterator;
- import java.util.Set;
- import server.utils.Log;
- public class Server implements Runnable {
- private ArrayList<ClientHandle> clients;
- private Selector selector;
- private Worker worker;
- public Server(Worker worker) {
- this.clients = new ArrayList<ClientHandle>();
- this.worker = new Worker();
- try {
- this.start();
- } catch (IOException e) {
- Log.e("An error occurred when trying to start the server.", e,
- this.getClass());
- }
- }
- public void start() throws IOException {
- Log.i("Server starting...", this.getClass());
- // Instantiate a new selector
- selector = Selector.open();
- // Create server socket and channel
- ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.configureBlocking(false);
- ServerSocket ss = ssc.socket();
- InetSocketAddress address = new InetSocketAddress(InetAddress
- .getLocalHost().getHostAddress(), 1337);
- ss.bind(address);
- Log.i("Opening port " + address.getPort() + " on address "
- + address.getAddress().toString().split("/")[1],
- this.getClass());
- // Register channel with selector
- ssc.register(selector, SelectionKey.OP_ACCEPT);
- Log.i("Start sequence complete.", this.getClass());
- }
- @Override
- public void run() {
- Log.i("Server running.", this.getClass());
- while (true) {
- // Wait for new things to happen
- try {
- selector.select();
- } catch (IOException e) {
- Log.e("Could not select in server thread.", e, this.getClass());
- }
- Set<SelectionKey> selectedKeys = selector.selectedKeys();
- Iterator<SelectionKey> it = selectedKeys.iterator();
- while (it.hasNext()) {
- SelectionKey key = it.next();
- if (!key.isValid()) {
- Log.w("Invalid key selected: " + key.toString(), this.getClass());
- continue;
- }
- if (key.isAcceptable()) {
- ClientHandle c = this.accept(key);
- it.remove();
- if (c != null) {
- clients.add(c);
- Log.i("Client connected: " + c.id(), this.getClass());
- }
- } else if (key.isReadable()) {
- this.read(key);
- it.remove();
- }
- }
- }
- }
- protected ClientHandle accept(SelectionKey key) {
- ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
- SocketChannel sc;
- try {
- sc = ssc.accept();
- sc.configureBlocking(false);
- } catch (IOException e) {
- Log.e("Could not accept socket connection.", e, this.getClass());
- return null;
- }
- // Register the socket with the selector
- SelectionKey k;
- try {
- k = sc.register(selector, SelectionKey.OP_READ);
- } catch (ClosedChannelException e) {
- Log.e(e, this.getClass());
- return null;
- }
- // Add the client to the list of connected clients
- return new ClientHandle(sc, k);
- }
- private void read(SelectionKey key) {
- SocketChannel sc = (SocketChannel) key.channel();
- ByteBuffer readBuffer = ByteBuffer.allocate(1024);
- int r;
- try {
- r = sc.read(readBuffer);
- } catch (IOException e) {
- // Remote end closed connection forcibly
- closeConnection(key);
- return;
- }
- if (r == -1) {
- // Remote side closed connection cleanly
- closeConnection(key);
- return;
- }
- worker.processMessage(readBuffer.array(), r);
- }
- private void closeConnection(SelectionKey key) {
- SocketChannel sc = (SocketChannel) key.channel();
- try {
- sc.close();
- } catch (IOException e) {
- Log.e("Error occurred when closing socket channel.", e,
- this.getClass());
- }
- key.cancel();
- }
- public void stop() {
- Log.i("Server stopping...", this.getClass());
- Log.i("Server stopped.", this.getClass());
- }
- public static String getLocalIpAddress() {
- InetAddress localaddr = null;
- try {
- localaddr = InetAddress.getLocalHost();
- } catch (UnknownHostException e) {
- Log.e("Could not get local IP.", e, Server.class);
- }
- return localaddr.toString().split("/")[1];
- }
- public static String getLocalExternalIpAddress() {
- try {
- for (Enumeration<NetworkInterface> en = NetworkInterface
- .getNetworkInterfaces(); en.hasMoreElements();) {
- NetworkInterface ni = en.nextElement();
- for (Enumeration<InetAddress> enumIpAddr = ni
- .getInetAddresses(); enumIpAddr.hasMoreElements();) {
- InetAddress inetAddress = enumIpAddr.nextElement();
- if (!inetAddress.isLoopbackAddress()) { // ignore 127.0.0.1
- return inetAddress.getHostAddress().toString();
- }
- }
- }
- } catch (SocketException ex) {
- }
- return null;
- }
- }
- package server.network.nio;
- import java.util.LinkedList;
- import java.util.Queue;
- import server.utils.Log;
- public class Worker implements Runnable {
- private Queue<String> queue = new LinkedList<String>();
- public void processMessage(byte[] data, int count) {
- byte[] copiedData = new byte[count];
- System.arraycopy(data, 0, copiedData, 0, count);
- synchronized (queue) {
- Log.d("Queue, in processMessage: " + System.identityHashCode(queue), this.getClass());
- queue.add(new String(copiedData));
- queue.notifyAll();
- }
- }
- @Override
- public void run() {
- Log.d("Worker running.", this.getClass());
- while (true) {
- Log.d("Worker starting new loop...", this.getClass());
- String msg;
- // Wait for new data to become available
- synchronized (queue) {
- Log.d("Queue, in run: " + System.identityHashCode(queue), this.getClass());
- while (queue.isEmpty()) {
- try {
- queue.wait();
- } catch (InterruptedException e) {
- // Swallow and wait some more...
- }
- }
- msg = queue.poll();
- }
- Log.i("Processed message from client: " + msg, this.getClass());
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement