Java/Java 구현

Java // 구현 // Client Socket // NIO Blocking

문스코딩 2018. 8. 6. 19:32

- NIO Blocking으로 구현된 클라이언트 소켓 추상 클래스

- "route()" 메소드를 재정의해서 사용해야 합니다.

- Singleton 객체로 구현

- Queue를 이용해서 다수의 데이터를 동시에 보내도 처리할 수 있도록 구현


public abstract class MySocket {

/* Field */
private static MySocket instance;
public SocketChannel socketChannel;
public Charset charset = Charset.forName("UTF-8");
private Queue<String> postQueue = new LinkedList<>(); // 전송할 데이터를 담아두는 Queue
private int bufferSize;
private boolean busy = false; // Queue를 사용하고 있는지

/* Constructor */
public MySocket(String host, short port, int bufferSize) throws RuntimeException {
// == singleton ==
if(instance != null) return;
instance = this;
this.bufferSize = bufferSize;
startSocket(host, port);
}

/* GetInstance */
public static MySocket getInstance() {
return instance;
}

/* StartSocket */
public void startSocket(String host, short port) throws RuntimeException {
Thread thread = new Thread() {
@Override
public void run() {
try {
socketChannel = SocketChannel.open();

// ### 블로킹방식 (명시적) ###
socketChannel.configureBlocking(true);

// ### connect(new InetSocketAddress) ###
socketChannel.connect(new InetSocketAddress(host, port));

} catch (IOException err) {
// TODO 오류 - 서버
err.printStackTrace();
}
receive();
}
};
thread.start();
}

/* StopSocket */
public void stopSocket() {
try {
if(socketChannel != null && socketChannel.isOpen()) {
socketChannel.close();
}
} catch (IOException e) {
// TODO 오류 - 서버
e.printStackTrace();
}
}

/* Receive */
public void receive() {
while(true) {
try {

// == read ==
ByteBuffer byteBuffer = ByteBuffer.allocate(bufferSize); // 1024
int byteCount = socketChannel.read(byteBuffer);
if(byteCount == -1) throw new IOException();

byteBuffer.flip();
String response = charset.decode(byteBuffer).toString();

// == route ==
route(response);
} catch (IOException e) {
// TODO 오류 - 서버
e.printStackTrace();
break;
}
}
}

/* Route */
public abstract void route ( String response );

/* Send */
public void send( String request ) {

postQueue.offer(request);
if(!busy) {
busy = true;
post();
}
}

/* Post */
private void post() {
String request = postQueue.poll();
Thread thread = new Thread() {
@Override
public void run() {
try {
try {
// == write ==
System.out.println(request);
ByteBuffer byteBuffer = charset.encode( request );
socketChannel.write(byteBuffer);

// == queue ==
if(postQueue.size() > 0) {
post();
} else {
busy = false;
}
} catch (NotYetConnectedException errA) {
errA.printStackTrace();
}
} catch (IOException errB) {
// TODO 오류 - 서버
errB.printStackTrace();
}
}
};
thread.start();
}

}


반응형