jdk nio多并发 长连接

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wuhanyms/article/details/84383412

java nio


一、服务器

1、初始化

(1)创建多路复用器selector

(2)创建服务器socket管道serversSocketChannel

(3)serversocket绑定服务端口

(4)设置服务器socket管道的阻塞方式为非阻塞式

(5)为服务器socket管道绑定selector

        Selector selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

2、端口监听和处理

(1)监听多路复用器selector

(2)获取客户端请求状态集selectedKeys

 

(3)循环处理每笔请求,判断每笔请求的状态并根据状态做相应处理

        while (true) {
        
            int n = selector.select();//监听多路复用器,看是否有客户端请求
            if (n <= 0)
                continue;
         
            Iterator<SelectionKey> it = selector.selectedKeys().iterator();//获取客户端请求状态集

            while (it.hasNext()) {
                SelectionKey key = it.next();
                //System.out.print(".");
             
                if (key.isAcceptable()) {//如果状态为acceptable,则为新连接
                    SocketChannel channel = ((ServerSocketChannel) key
                            .channel()).accept();//获取socket管道
                    if (channel != null) {
                        // new connection from client, register it
                        channel.configureBlocking(false);
                        channel.register(selector, SelectionKey.OP_READ);

                       /**

                       */自定义处理逻辑

                       */

                       */
                }

                if (key.isReadable()) {//如果状态为Readable,则该已建立连接,读取请求内容
                    
                    SocketChannel channel = (SocketChannel) key.channel();
                    m_buffer.clear(); // empty the buffer
                    while ((count = channel.read(m_buffer)) > 0) {
                          //读取请求流并作处理
                    }

                    if (count < 0) {//如果出现socket关闭标示,则关闭管道
                        // Close channel on EOF.
                        channel.close();
                    }
                }
                it.remove();//请求处理完后清除请求集
            }
        }

二、客户端

以任何方式发起TCP连接和请求即可 

 

 

展开阅读全文

求助:Java Nio 保持连接分发消息

07-28

最近闲来无事想做个小型的聊天工具,客户端用android已经做好了,跟服务器的交互不想使用Http的方式,改用socket长连接,这样的话消息能及时送达就避免了http不断轮询的消耗。rn网上关于Java NIO大部分都是些基础的例子和结构,关于长连接的实在是很少,rn现在已经能正常监听请求和读写内容,但是没办法让服务器发送消息到指定的一台或若干台客户端,老的JavaIO可以通过保存Socket,但是nio每次事件都是一个新的SelectionKey,保存了也是旧的(目前的理解),请教各位,如何才能保存下跟每个客户端的会话呢,如下是部分代码rn[code=Java]rnpublic class SeekServer extends Threadrn private final int ACCPET_PORT = 55555;rn private final int TIME_OUT = 3000;rn private Selector mSelector = null;rn private ServerSocketChannel mSocketChannel = null;rn private ServerSocket mServerSocket = null;rn private InetSocketAddress mAddress = null;rn rn public SeekServer() rn long sign = System.currentTimeMillis();rn try rn mSocketChannel = ServerSocketChannel.open();rn if(mSocketChannel == null) rn System.out.println("can't open server socket channel");rn rn mServerSocket = mSocketChannel.socket();rn mAddress = new InetSocketAddress(ACCPET_PORT);rn mServerSocket.bind(mAddress);rn Log.i("server bind port is " + ACCPET_PORT);rn mSelector = Selector.open();rn mSocketChannel.configureBlocking(false);rn SelectionKey key = mSocketChannel.register(mSelector, SelectionKey.OP_ACCEPT);rn key.attach(new Acceptor());rn Log.i("Seek server startup in " + (System.currentTimeMillis() - sign) + "ms!");rn catch (ClosedChannelException e) rn Log.e(e.getMessage());rn catch (IOException e) rn Log.e(e.getMessage());rn rn rn rn public void run() rn Log.i("server is listening...");rn while(!Thread.interrupted()) rn try rn if(mSelector.select(TIME_OUT) > 0) rn Log.i("find a new selection key");rn Set keys = mSelector.selectedKeys();rn Iterator iterator = keys.iterator();rn SelectionKey key = null;rn while(iterator.hasNext()) rn key = iterator.next();rn Runnable at = (Runnable) key.attachment();rn if(at != null) rn at.run();rn rn keys.clear();rn rn rn catch (IOException e) rn Log.e(e.getMessage());rn rn rn rnrn class Acceptor implements Runnablernrn public void run()rn try rn SocketChannel sc = mSocketChannel.accept();rn [color=#FF0000]new Handler(mSelector, sc)[/color];//开始处理这个Channelrn catch (ClosedChannelException e) rn Log.e(e);rn catch (IOException e) rn Log.e(e);rn rn rn rnrn[/code] 论坛

没有更多推荐了,返回首页