Create a Server with ServerSocketChannel - Java Network

Java examples for Network:Socket Channel

Description

Create a Server with ServerSocketChannel

Demo Code

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
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.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Main {
  private Map<SocketChannel, List<byte[]>> keepDataTrack = new HashMap<>();
  private ByteBuffer buffer = ByteBuffer.allocate(2 * 1024);

  private void startEchoServer() {
    try (Selector selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
      if ((serverSocketChannel.isOpen()) && (selector.isOpen())) {
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF,
            256 * 1024);/*from  w w w .j  a v a2 s.c  o  m*/
        serverSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
        serverSocketChannel.bind(new InetSocketAddress(5555));
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
          selector.select();
          Iterator keys = selector.selectedKeys().iterator();
          while (keys.hasNext()) {
            SelectionKey key = (SelectionKey) keys.next();
            keys.remove();
            if (!key.isValid()) {
              continue;
            }
            if (key.isAcceptable()) {
              accept(key, selector);
            } else if (key.isReadable()) {
              read(key);
            } else if (key.isWritable()) {
              write(key);
            }
          }
        }
      } else {
        System.out.println("The server socket channel or selector cannot be opened!");
      }

    } catch (IOException ex) {
      System.err.println(ex);
    }
  }

  private void accept(SelectionKey key, Selector selector) throws IOException {
    ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
    SocketChannel socketChannel = serverChannel.accept();
    socketChannel.configureBlocking(false);
    System.out.println("Incoming connection from: "
        + socketChannel.getRemoteAddress());
    socketChannel.write(ByteBuffer.wrap("Hello!\n".getBytes("UTF-8")));
    keepDataTrack.put(socketChannel, new ArrayList<byte[]>());
    socketChannel.register(selector, SelectionKey.OP_READ);
  }

  private void read(SelectionKey key) {
    try {
      SocketChannel socketChannel = (SocketChannel) key.channel();
      buffer.clear();
      int numRead = -1;
      try {
        numRead = socketChannel.read(buffer);
      } catch (IOException e) {
        System.err.println("Cannot read error!");
      }
      if (numRead == -1) {
        this.keepDataTrack.remove(socketChannel);
        System.out.println("Connection closed by: "
            + socketChannel.getRemoteAddress());
        socketChannel.close();
        key.cancel();
        return;
      }
      byte[] data = new byte[numRead];
      System.arraycopy(buffer.array(), 0, data, 0, numRead);
      System.out.println(new String(data, "UTF-8") + " from "
          + socketChannel.getRemoteAddress());

      SocketChannel s = (SocketChannel) key.channel();
      List<byte[]> channelData = keepDataTrack.get(s);
      channelData.add(data);

      key.interestOps(SelectionKey.OP_WRITE);
      
    } catch (IOException ex) {
      System.err.println(ex);
    }
  }
  private void write(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    List<byte[]> channelData = keepDataTrack.get(socketChannel);
    Iterator<byte[]> its = channelData.iterator();
    while (its.hasNext()) {
      byte[] it = its.next();
      its.remove();
      socketChannel.write(ByteBuffer.wrap(it));
    }
    key.interestOps(SelectionKey.OP_READ);
  }
  public static void main(String[] args) {
    Main main = new Main();
    main.startEchoServer();
  }
}

Related Tutorials