java nio 이용하여 논블로킹 소켓서버구현하는 주요 로직
private Selector selector; private ServerSocketChannel ssc; private ServerSocket ss; private Vector<SocketChannel> clients = new Vector<SocketChannel>(); public void initServer() throws Exception { selector = Selector.open(); ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); ss = ssc.socket(); InetSocketAddress isa = new InetSocketAddress(SERVER, PORT); ss.bind(isa); ssc.register(selector, SelectionKey.OP_ACCEPT); } public void startServer() throws IOException { System.out.println("서버가 시작되었습니다."); while (true) { System.out.println("\n\n클라이언트를 기다리고 있습니다."); selector.select(); Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); if (key.isAcceptable()) accept(key); else if (key.isReadable()) read(key); it.remove(); } } } private void accept(SelectionKey key) throws IOException { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); if (client == null) { System.out.println("Connection이 잘못되었습니다."); return; } client.configureBlocking(false); client.register(selector, SelectionKey.OP_READ); clients.add(client); } private void read(SelectionKey key) { SocketChannel sc = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocateDirect(1024); try { int read = sc.read(buffer); if (read == -1) throw new Exception(); System.out.println("클라이언트로부터 " + read + " 바이트 읽음 : " + buffer); buffer.flip(); Iterator<SocketChannel> it = clients.iterator(); while (it.hasNext()) { SocketChannel soc = (SocketChannel) it.next(); if (soc != null) { soc.write(buffer); buffer.rewind(); } } if (buffer != null) { buffer.clear(); buffer = null; } } catch (Exception e) { try { sc.close(); } catch (Exception ee) { ee.printStackTrace(); } clients.remove(sc); System.out.println(sc + " 클라이언트가 나갔습니다."); } }