我正在尝试使用“The Rox Java NIO Tutorial”中基于java NIO(非阻塞)的服务器端代码。有很多传入的套接字连接,我只想接受100.所以如果有100个活动连接,那么新的连接应该被拒绝/拒绝。但是怎么做呢?只有方法ServerSocketChannel.accept()返回SocketChannel对象。使用该对象我可以调用socketChannel.socket()。close(),但是连接已经打开。以下是代码的一部分:
@Override
public void run() {
while (true) {
try {
// Wait for an event one of the registered channels
this.selector.select();
// Iterate over the set of keys for which events are available
Iterator selectedKeys = this.selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = (SelectionKey) selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
}
// Check what event is available and deal with it
if (key.isAcceptable()) {
this.accept(key);
} else if (key.isReadable()) {
this.read(key);
} else if (key.isWritable()) {
this.write(key);
}
}
} catch (Exception e) {
logger.warn("Reading data", e);
}
}
}
并接受()方法:
private void accept(SelectionKey key) throws IOException {
// For an accept to be pending the channel must be a server socket channel.
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
// Accept the connection and make it non-blocking
if (noOfConnections < MAX_CONNECTIONS) {
SocketChannel socketChannel = serverSocketChannel.accept();
Socket socket = socketChannel.socket();
socket.setKeepAlive(true);
socketChannel.configureBlocking(false);
// Register the new SocketChannel with our Selector, indicating
// we'd like to be notified when there's data waiting to be read
socketChannel.register(this.selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);//listener for incoming data: READ from client, WRITE to client
noOfConnections++;
logger.info("Accepted: " + socket.getRemoteSocketAddress().toString());
} else {
// REJECT INCOMING CONNECTION, but how?
logger.warn("Server is full: " + noOfConnections + " / " + MAX_CONNECTIONS);
}
}
如果不接受连接,则反复调用accept()方法。
感谢您的帮助!
答案 0 :(得分:1)
没有办法实现这一目标,但我怀疑这是你真正想要的,或者至少是你应该做的。
如果要停止接受连接,请将服务器套接字通道的选择键中的interestOps更改为零,并在准备再次接受时将其更改回OP_ACCEPT
。在此期间,isAcceptable()
将永远不会成立,因此您描述的问题不会发生。
然而,这不会导致进一步的连接被拒绝:它会将它们留在积压队列中,在我看来,它们属于TCP的设计者。如果积压队列填满,则会出现另一种失败行为:它在客户端中的影响取决于系统:连接拒绝和/或超时。
答案 1 :(得分:0)
我认为积压队列的任何调整都不是一个好的解决方案。但可能,你可以停止听。
答案 2 :(得分:0)
好吧,我接下来就解决了这个问题: 套接字上的挂起状态连接属于&#34; middle_state&#34;,这意味着您无法控制/拒绝它们。 可以由特定VM以不同方式使用/忽略/处理积压套接字参数。 这意味着您必须接受特定连接才能接收相关对象并进行操作。
使用一个线程接受连接,将接受的连接传递给第二个线程进行处理。 为活动连接数创建一些变量。 现在,当活动连接数小于希望最大值时,接受连接,将数字增加1,然后传递给第二个线程进行处理。 否则,接受连接并立即关闭。
此外,在连接进程线程中,完成后,将活动连接数减少1,以指示还有一个可用空闲通道。
美国东部时间:刚刚制作了&#34; stub&#34;用于Java.Net NIO的服务器机制。 可能适合OP需求:!sharedpreferences.getString(MyPREFERENCES, "").equals("")