简体   繁体   中英

AsynchronousServerSocketChannel.accept is only accepting a one connection

I have a small server setup where I'm trying to use event based connection sockets, so that a handler is called on each incoming connection. It works great for the first connection, but no new connections are accepted after the first one.

I just close the client connection when it comes in for simplicity. Also, yes the server is still running after the first connection, it doesn't terminate.

Here is the code:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


public class ServerTest
{
static CompletionHandler<AsynchronousSocketChannel, Object> handler =
        new CompletionHandler<AsynchronousSocketChannel, Object>() {
        @Override
        public void completed(AsynchronousSocketChannel result, Object attachment) {
            System.out.println(attachment + " completed with " + result + " bytes written");
            try {
                result.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void failed(Throwable e, Object attachment) {
            System.err.println(attachment + " failed with:");
            e.printStackTrace();
        }
    };

public static void main(String[] args) throws Exception
{
    AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(Executors.newSingleThreadExecutor());
    System.out.println("STARTING");
    AsynchronousServerSocketChannel ssc =
        AsynchronousServerSocketChannel.open(group).bind(new InetSocketAddress("localhost", 9999));

    System.out.println("BOUND");
    ssc.accept(ssc, handler);

    group.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);

}
}

public abstract void accept(A attachment, CompletionHandler handler)

This method initiates an asynchronous operation to accept a connection made to this channel's socket. The handler parameter is a completion handler that is invoked when a connection is accepted (or the operation fails). The result passed to the completion handler is the AsynchronousSocketChannel to the new connection.

Read more here

This means that it initializes an asynchronous thread to accept incoming connections. This also means that it'll take the first connection and forward it to the asynchronous thread and then wait for more connections. To allow more clients to connect you must invoke an accept method inside of the overwritten completed function as well.

Here is an example,

server.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
@Override
public void completed(AsynchronousSocketChannel chan, Void attachment) {
    System.out.println("Incoming connection...");
    server.accept(null, this); //add this

    //...

It should be noted that for every client, a new AsynchronousSocketChannel result is produced. That being said if you were to print out 'chan', it'll result in different objects.

Distinct client objects

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM