0
서버에 메시지를 보내고 응답을받는 클라이언트 응용 프로그램을 작성하고 싶습니다. 클라이언트는 응답에 관계없이 여러 번 메시지를 보냅니다 (예 : 주기적으로 초 단위로 메시지 하나). 응답이 되돌아 오면 클라이언트는 가능한 한 빨리 응답하려고합니다.java.nio.channels.SocketChannel 정기 쓰기 및 즉시 읽기
다음은 클라이언트에서 작동하지 않는 코드입니다. startReading()
메서드에서 실행 가능한 인스턴스가 서버의 응답에 응답해야하지만 필요하지 않습니다. 이 경우 _channel.write(buffer)
이 올바르게 반환되지 않습니다.
다음 코드 또는 위의 동작을 구현하는 다른 방법의 문제점을 알려주십시오.
public class MyClient {
private SocketChannel _channel = null;
private Selector _selector = null;
private InetSocketAddress _addr = new InetSocketAddress("127.0.0.1", 5555);
public MyClient() {
_selector = SelectorProvider.provider().openSelector();
_channel = SocketChannel.open();
_channel.configureBlocking(false);
startReading();
_channel.connect(_addr);
}
private void startReading() throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(1024);
_channel.register(_selector, SelectionKey.OP_READ, buffer);
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
while (0 < _selector.select()) {
Iterator<SelectionKey> keyIterator = _selector.selectedKeys().iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
keyIterator.remove();
if (key.isReadable())
read(key);
}
}
}
catch (IOException e) {}
}
};
ExecutorService service = Executors.newFixedThreadPool(1);
service.execute(runnable);
}
private void read(SelectionKey key) throws IOException {
// do some reading operations
}
@Override
public void run() {
ByteBuffer buffer = ByteBuffer.allocate(1024);
// write message to buffer
buffer.flip();
try {
_channel.write(buffer);
} catch (IOException e) {}
}
public static void main (String[] args) {
MyClient client = new MyClient();
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.scheduleAtFixedRate(client, 1000, 1000, TimeUnit.MILLISECONDS);
}
}
왜 하나의 채널에 대해 선택기를 사용하면 어떨까요? 결국 백그라운드 스레드에서 효과적으로 수행하는 작업은 차단 읽기를 다시 구현하는 것입니다. 따라서 채널을 차단하도록 구성하고 복잡한 구조없이 백그라운드 스레드에서 일반 읽기를 수행 할 수 있습니다. – Holger
단일 채널에 선택기를 사용하는 이유는 무엇입니까? 위의 코드는 내 문제의 단순화 된 모델이기 때문에. 내가 진정으로하고 싶은 것은 더욱 복잡합니다. – user4047360