我是NIO的新手,我需要使用下一个api创建简单的非阻塞客户端:
void start();
void send(String msg);
void stop();
Start方法应为指定的主机和端口创建连接。 stop方法应该停止客户端并释放连接。 send应该向服务器发送消息。
所以我阅读了文档并创建了简单的客户端:
public class NonBlockingNIOClient {
private DatagramChannel channel;
public final static int MAX_PACKET_SIZE = 65507;
private static final Logger LOGGER = LoggerFactory.getLogger(NonBlockingNIOStatsDClient.class);
public NonBlockingNIOStatsDClient(String host, int port) {
this.host = host;
this.port = port;
}
public void start() {
try {
channel = DatagramChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress(getHost(), getPort()));
while (!channel.isConnected()) {
LOGGER.debug("still connecting");
}
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(channel.isConnected()) {
}
}
});
thread.start();
} catch(IOException e) {
throw new ClientException("Failed to start client", e);
}
}
public void stop() {
try {
channel.disconnect();
} catch(IOException e) {
throw new StatsDClientException("Failed to stop client", e);
}
}
@Override
public void send(String msg) {
LOGGER.debug("send: {}", msg);
Validate.notBlank(msg, "message to sand cannot be blank");
ByteBuffer buf = ByteBuffer.allocate(MAX_PACKET_SIZE);
buf.clear();
buf.put(msg.getBytes());
buf.flip();
try {
channel.write(buf);
} catch(IOException e) {
getErrorHandler().handle(e);
}
}
}
我如何从文档中了解channel.configureBlocking(false);
并不能保证来自频道的写方法能够在非阻塞模式下工作。我想我需要使用选择器来实现非阻塞行为。但是当我试着做下一个时:
Selector selector = null;
try {
selector = Selector.open();
channel.register(selector, SelectionKey.OP_WRITE);
while(channel.isConnected()){
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while(iterator.hasNext())
{
SelectionKey key = iterator.next();
if(key.isWritable())
{
//do send
}
iterator.remove();
}
}
selector.close();
}
在这种情况下,客户端不响应send()
方法,因为客户端被while(channel.isConnected())
阻止。您有什么建议我可以使用启动方法并同时使用选择器。