Server.java
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.charset.Charset;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
public class IotServer {
Selector selector;
ServerSocketChannel serverSocketChannel;
List<Client> connections = new Vector<Client>();
void startServer() {
try {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(5001));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (Exception e) {
if(serverSocketChannel.isOpen()) { stopServer(); }
return;
}
Thread thread = new Thread() {
@Override
public void run() {
while(true) {
try {
int keyCount = selector.select();
if(keyCount == 0) { continue; }
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
if (selectionKey.isAcceptable()) {
accept(selectionKey);
} else if (selectionKey.isReadable()) {
Client client = (Client)selectionKey.attachment();
client.receive(selectionKey);
} else if (selectionKey.isWritable()) {
Client client = (Client)selectionKey.attachment();
client.send(selectionKey);
}
iterator.remove();
}
} catch (Exception e) {
if(serverSocketChannel.isOpen()) { stopServer(); }
break;
}
}
}
};
thread.start();
System.out.println("서버 멈춤");
}
void stopServer() {
try {
Iterator<Client> iterator = connections.iterator();
while(iterator.hasNext()) {
Client client = iterator.next();
client.socketChannel.close();
iterator.remove();
}
if(serverSocketChannel!=null && serverSocketChannel.isOpen()) {
serverSocketChannel.close();
}
if(selector!=null && selector.isOpen()) {
selector.close();
}
System.out.println("서버 멈춤");
} catch (Exception e) {}
}
void accept(SelectionKey selectionKey) {
try {
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
SocketChannel socketChannel = serverSocketChannel.accept();
String message = "[연결 수락: " + socketChannel.getRemoteAddress() + ": " + Thread.currentThread().getName() + "]";
System.out.println(message);
Client client = new Client(socketChannel);
connections.add(client);
System.out.println("[연결 개수: " + connections.size() + "]");
} catch(Exception e) {
if(serverSocketChannel.isOpen()) { stopServer(); }
}
}
class Client {
SocketChannel socketChannel;
String sendData;
Client(SocketChannel socketChannel) throws IOException {
this.socketChannel = socketChannel;
socketChannel.configureBlocking(false);
SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_READ);
selectionKey.attach(this);
}
void receive(SelectionKey selectionKey) {
try {
ByteBuffer byteBuffer = ByteBuffer.allocate(100);
//상대방이 비정상 종료를 했을 경우 자동 IOException 발생
int byteCount = socketChannel.read(byteBuffer);
//상대방이 SocketChannel의 close() 메소드를 호출할 경우
if(byteCount == -1) {
throw new IOException();
}
String message = "[요청 처리: " + socketChannel.getRemoteAddress() + ": " + Thread.currentThread().getName() + "]";
System.out.println(message);
byteBuffer.flip();
Charset charset = Charset.forName("UTF-8");
String data = charset.decode(byteBuffer).toString();
System.out.println(data);
for(Client client : connections) {
client.sendData = data;
SelectionKey key = client.socketChannel.keyFor(selector);
key.interestOps(SelectionKey.OP_WRITE);
}
selector.wakeup();
String[] receivedMessage = null;
receivedMessage = data.split("#");
System.out.println(receivedMessage[0]+"\n"+receivedMessage[1]);
if(receivedMessage[0].equals("hello")){
if(receivedMessage[1].equals("server")) {
System.out.println("split");
}
}
} catch(Exception e) {
try {
connections.remove(this);
String message = "[클라이언트 통신 안됨: " + socketChannel.getRemoteAddress() + ": " + Thread.currentThread().getName() + "]";
System.out.println(message);
socketChannel.close();
} catch (IOException e2) {}
}
}
void send(SelectionKey selectionKey) {
try {
Charset charset = Charset.forName("UTF-8");
ByteBuffer byteBuffer = charset.encode(sendData);
socketChannel.write(byteBuffer);
selectionKey.interestOps(SelectionKey.OP_READ);
selector.wakeup();
} catch(Exception e) {
try {
String message = "[클라이언트 통신 안됨: " + socketChannel.getRemoteAddress() + ": " + Thread.currentThread().getName() + "]";
System.out.println(message);
connections.remove(this);
socketChannel.close();
} catch (IOException e2) {}
}
}
}
public static void main(String[] args) {
IotServer server = new IotServer();
server.startServer();
}
}