Java 使用NIO的非阻塞客户端
我是NIO新手,需要使用下一个api创建简单的非阻塞客户端:Java 使用NIO的非阻塞客户端,java,client,nio,nonblocking,Java,Client,Nio,Nonblocking,我是NIO新手,需要使用下一个api创建简单的非阻塞客户端: void start(); void send(String msg); void stop(); Start方法应为指定的主机和端口创建连接。 stop方法应停止客户端并释放连接。 send应该将消息发送到服务器 因此,我阅读了文档并创建了简单客户端: public class NonBlockingNIOClient { private DatagramChannel channel; public fina
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();
}
Selector=null;
试一试{
选择器=selector.open();
通道寄存器(选择器、选择键、操作写入);
while(channel.isConnected()){
selector.select();
迭代器迭代器=选择器。selectedKeys()。迭代器();
while(iterator.hasNext())
{
SelectionKey=iterator.next();
if(key.isWritable())
{
//派
}
iterator.remove();
}
}
selector.close();
}
在这种情况下,客户端不响应send()
方法,因为客户端在(channel.isConnected())
时被阻止。您对我如何使start方法可用并同时使用选择器有何建议 “while(channel.isConnected())”上显然毫无意义的自旋循环最初的目的是什么?把它取下来,好的。所以,我认为我需要使用队列,send()方法将把要发送的消息放入队列中,而“if(key.iswriteable()){}”块中的一些逻辑将从队列中获取消息并将其发送到服务器。没关系,这种方法有意义吗?我宁愿问你为什么你认为你需要在客户机中使用NIO。除非你处理的是多个服务器,否则就没有意义了。我只是想了解如何实现这样的客户端。不,我不知道将使用多少台服务器,也不知道使用了哪种技术(I/O或NIO)来实现服务器。我只是想知道它一般如何实现,以何种方式实现,目前仅此而已。我强烈建议您首先使用java.net
,然后再看看您是否需要对它做更多的工作。