【发布时间】:2014-09-16 17:56:37
【问题描述】:
我想编写一个向服务器发送消息并接收其回复的客户端应用程序。无论回复如何,客户端都会多次发送消息(例如,每隔一秒定期发送一条消息)。当回复回来时,客户希望尽快做出响应。
这是客户端的代码,它不起作用。我希望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);
}
}
【问题讨论】:
-
你为什么要为单个频道使用选择器?毕竟,您在后台线程中有效地做的是重新实现阻塞读取。因此,您可以简单地将通道配置为阻塞并在后台线程中进行普通读取,而无需复杂的结构。
-
为什么对单通道使用选择器?因为上面的代码是我的问题的简化模型。我真正想做的事情更复杂。
标签: java client selector nio socketchannel