我应该如何使用AsynchronousServerSocketChannel接受连接? [英] How should I use AsynchronousServerSocketChannel for accepting connections?

查看:821
本文介绍了我应该如何使用AsynchronousServerSocketChannel接受连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Java 7和2 NIO写一个异步服务器。

不过,我应该如何使用<一个href=\"http://docs.oracle.com/javase/7/docs/api/java/nio/channels/AsynchronousServerSocketChannel.html\"><$c$c>AsynchronousServerSocketChannel?

例如。如果我开始:

 最后AsynchronousServerSocketChannel服务器=
    AsynchronousServerSocketChannel.open()。绑定(
        新的InetSocketAddress(端口));

后来,当我做 server.accept(),程序的终止,因为调用的异步的。如果我把code无限循环,一个 AcceptPendingException 被抛出。

有关如何使用编写一个简单的异步服务器的任何建议 AsynchronousServerSocketChannel

下面是我的完整的例子(在JavaDoc类似的例子):

 进口java.io.IOException异常;
进口java.net.InetSocketAddress;
进口java.nio.channels.AsynchronousServerSocketChannel;
进口java.nio.channels.AsynchronousSocketChannel;
进口java.nio.channels.CompletionHandler;公共类AsyncServer {    公共静态无效的主要(字串[] args){
        INT端口= 8060;
        尝试{
            最后AsynchronousServerSocketChannel服务器=
                    AsynchronousServerSocketChannel.open()。绑定(
                            新的InetSocketAddress(端口));            的System.out.println(服务器监听+端口);            server.accept(客户端连接
                    新CompletionHandler&LT; AsynchronousSocketChannel,对象&gt;(){
                公共无效完成(AsynchronousSocketChannel CH,对象ATT){
                    的System.out.println(接受连接);                    //接受下一个连接
                    server.accept(客户端连接,这一点);                    //处理这个连接
                    // TODO手柄(CH);
                }                公共无效失败(EXC的Throwable,对象ATT){
                    的System.out.println(无法接受连接);
                }
            });
        }赶上(IOException异常五){
            e.printStackTrace();
        }
    }
}


解决方案

您在正确的轨道上,调用accept()从已完成的回调,以接受更多连接应该工作。

一个简单的(但丑陋的)的方式来prevent从终止线程是简单地循环,直到线程被中断。

  //是,睡眠()是邪恶的,但有时我不在乎
而(真){
    视频下载(1000);
}

一个更清洁的方法是使用 AsynchronousChannelGroup 。例如:

  AsynchronousChannelGroup组= AsynchronousChannelGroup.withThreadPool(执行人
            .newSingleThreadExecutor());
AsynchronousServerSocketChannel服务器= AsynchronousServerSocketChannel.open(集团).bind(
            新的InetSocketAddress(端口));//(插入server.accept()这里的逻辑)//等到group.shutdown()/ shutdownNow时(),或者线程被中断:
group.awaitTermination(Long.MAX_VALUE,TimeUnit.SECONDS);

您可以调整线程的处理方式,请参阅<一个href=\"http://docs.oracle.com/javase/7/docs/api/java/nio/channels/AsynchronousChannelGroup.html\">AsynchronousChannelGroup API文档以获取更多信息。

I would like to write an asynchronous server using Java 7 and NIO 2.

But how should I use AsynchronousServerSocketChannel?

E.g. if I start with:

final AsynchronousServerSocketChannel server = 
    AsynchronousServerSocketChannel.open().bind(
        new InetSocketAddress(port));

Then when I do server.accept(), the program terminates because that call is asynchronous. And if I put that code in an infinite loop, an AcceptPendingException is thrown.

Any suggestions on how to write a simple asynchronous server using AsynchronousServerSocketChannel?

Here is my full example (similar to the example in the JavaDoc):

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

public class AsyncServer {

    public static void main(String[] args) {
        int port = 8060;
        try {
            final AsynchronousServerSocketChannel server = 
                    AsynchronousServerSocketChannel.open().bind(
                            new InetSocketAddress(port));

            System.out.println("Server listening on " + port);

            server.accept("Client connection", 
                    new CompletionHandler<AsynchronousSocketChannel, Object>() {
                public void completed(AsynchronousSocketChannel ch, Object att) {
                    System.out.println("Accepted a connection");

                    // accept the next connection
                    server.accept("Client connection", this);

                    // handle this connection
                    //TODO handle(ch);
                }

                public void failed(Throwable exc, Object att) {
                    System.out.println("Failed to accept connection");
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

解决方案

You are on the right track, calling accept() from the completed callback in order to accept more connections should work.

A simple (but ugly) way to prevent the thread from terminating is simply to loop until the thread is interrupted.

// yes, sleep() is evil, but sometimes I don't care
while (true) {
    Thread.sleep(1000);
}

A cleaner way is to use AsynchronousChannelGroup. For instance:

AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(Executors
            .newSingleThreadExecutor());
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(group).bind(
            new InetSocketAddress(port));

// (insert server.accept() logic here)

// wait until group.shutdown()/shutdownNow(), or the thread is interrupted:
group.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);

You can tune how threads are handled, see the AsynchronousChannelGroup API docs for more information.

这篇关于我应该如何使用AsynchronousServerSocketChannel接受连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆