- 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();
}
}
반응형
'Java > Java 구현' 카테고리의 다른 글
Java // 구현 // Client SocketChannel (in Server) // NIO NonBlocking (0) | 2018.08.03 |
---|---|
Java // 구현 // Server Socket // NIO NonBlocking (0) | 2018.08.03 |
Java FX // 구현 // GridPane // DataBinding (0) | 2018.07.26 |