简体   繁体   English

Java7异步NIO2服务器上的连接拒绝

[英]Connection refusal on Java7 async NIO2 server

I have written a async socketserver using java 7 nio2. 我使用java 7 nio2编写了一个异步socketserver。

Here is a snipper of the Server. 这是服务器的一个片段。

public class AsyncJava7Server implements Runnable, CounterProtocol, CounterServer{
    private int port = 0;
    private AsynchronousChannelGroup group;
    public AsyncJava7Server(int port) throws IOException, InterruptedException, ExecutionException {
        this.port = port;
    }

    public void run() {
        try {
            String localhostname = java.net.InetAddress.getLocalHost().getHostName();
            group = AsynchronousChannelGroup.withThreadPool(
                 Executors.newCachedThreadPool(new NamedThreadFactory("Channel_Group_Thread")));

            // open a server channel and bind to a free address, then accept a connection
            final AsynchronousServerSocketChannel asyncServerSocketChannel =
                           AsynchronousServerSocketChannel.open(group).bind(
                                 new InetSocketAddress(localhostname, port));

            asyncServerSocketChannel.accept(null, 
                 new CompletionHandler <AsynchronousSocketChannel, Object>() {
                            @Override
                            public void completed(final AsynchronousSocketChannel asyncSocketChannel, 
                                      Object attachment) {
                                    // Invoke simple handle accept code - only takes about 10 milliseconds.
                                    handleAccept(asyncSocketChannel); 
                                    asyncServerSocketChannel.accept(null, this);
            }
                            @Override
                            public void failed(Throwable exc, Object attachment) {
                                System.out.println("***********" + exc  + " statement=" + attachment);  
            }
                 });

and here is a snippet of the client code which tries to connect... 这是一个试图连接的客户端代码片段

public class AsyncJava7Client implements CounterProtocol, CounterClientBridge {
    AsynchronousSocketChannel asyncSocketChannel;

    private String serverName= null;
    private int port;
    private String clientName;

    public AsyncJava7Client(String clientName, String serverName, int port) throws IOException {
        this.clientName = clientName;
        this.serverName = serverName;
        this.port = port;
    }

    private void connectToServer() {
        Future<Void> connectFuture = null;
        try {
            log("Opening client async channel...");
            asyncSocketChannel = AsynchronousSocketChannel.open();

            // Connecting to server
            connectFuture = asyncSocketChannel.connect(new InetSocketAddress("Alex-PC", 9999));
       } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
       }
       // open a new socket channel and connect to the server
       long beginTime  = 0;
       try {
           // You have two seconds to connect. This will throw exception if server is not there.
           beginTime = System.currentTimeMillis();
           Void connectVoid = connectFuture.get(15, TimeUnit.SECONDS);
       } catch (Exception ex) {
           //EXCEPTIONS THROWN HERE AFTER ABOUT 150 CLIENTS
           long endTime = System.currentTimeMillis();
           long timeTaken = endTime - beginTime;
           log("************* TIME TAKEN=" + timeTaken);
           ex.printStackTrace();
           throw new RuntimeException(ex);
       }
 }

I have a test which fires off clients. 我有一个测试可以解雇客户。

 @Test
 public void testManyClientsAtSametime() throws Exception {
     int clientsize = 150;
     ScheduledThreadPoolExecutor executor = 
            (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(clientsize + 1, 
                new NamedThreadFactory("Test_Thread"));
     AsyncJava7Server asyncJava7Server = startServer();
     List<AsyncJava7Client> clients = new ArrayList<AsyncJava7Client>();
     List<Future<String>> results = new ArrayList<Future<String>>();

     for (int i = 0; i < clientsize; i++) {
         // Now start a client
         final AsyncJava7Client client = 
               new AsyncJava7Client("client" + i, InetAddress.getLocalHost().getHostName(), 9999);
         clients.add(client);
     }

     long beginTime = System.currentTimeMillis();
     Random random = new Random();
     for (final AsyncJava7Client client: clients) {
         Callable<String> callable = new Callable<String>() {
             public String call() {
                 ...
                 ... invoke APIs to connect client to server
                 ...
                 return counterValue;
             }
     };

     long delay = random.nextLong() % 10000;  // somewhere between 0 and 10 seconds.
     Future<String> startClientFuture = executor.schedule(callable, delay, TimeUnit.MILLISECONDS);
     results.add(startClientFuture);
 }

It works super for about 100 clients. 它适用于大约100个客户。 At about 140+ I get a load of exceptions in the client - when it tries to connect. 在大约140+时,我在客户端遇到大量异常 - 当它尝试连接时。 The exception is: java.util.concurrent.ExecutionException: java.io.IOException: The remote computer refused the network connection. 例外情况是:java.util.concurrent.ExecutionException:java.io.IOException:远程计算机拒绝网络连接。

My test is on a single laptop running windows 7. When it bombs out I check the TCP connections and there about 500 - 600 connections -that's ok. 我的测试是在一台运行Windows 7的笔记本电脑上。当它轰炸时,我检查TCP连接,那里有大约500 - 600个连接 - 这没关系。 AS I have similiar JDK 1.0 java.net socket programs that can handle 4,000 TCP connections. 我有类似的JDK 1.0 java.net套接字程序,可以处理4,000个TCP连接。

No exceptions or anything dodgy looking in server. 在服务器中没有例外或任何狡猾的东西。

So I am at a loss as to what could be wrong here. 所以我不知道这里可能出现什么问题。 any ideas? 有任何想法吗?

Try using the form of bind that accepts a backlog limit and set that to a higher number. 尝试使用接受积压限制的bind形式并将其设置为更高的数字。 For example: 例如:

            final AsynchronousServerSocketChannel asyncServerSocketChannel =
                       AsynchronousServerSocketChannel.open(group).bind(
                             new InetSocketAddress(localhostname, port), 1000);

I don't know what the win7 implementation limit is by default but can be a cause of refused connections. 我不知道默认情况下win7实现限制是什么,但可能是拒绝连接的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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