`
youzifei
  • 浏览: 66723 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

SocketChannel 例子2

阅读更多

Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们。

在服务端我们可以使用非阻塞的方式。 下面是一段server端的程序。 client 可以采用阻塞方式来请求。

 

NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey, 我们读取这些Key, 就会获得我们刚刚注册过的socketchannel,然后,我们从 这个Channel中读取数据,放心,包准能够读到,接着我们可以处理这些数据。

Selector内部原理实际是在做一个对所注册的channel的轮询访问,不断的轮询(目前就这一个算法),一旦轮询到一个channel有所注册的事情发生,比如数据来了,他就会站起来报告,交出一把钥匙,让我们通过这把钥匙来读取这个channel的内容。

 

做一个备忘吧。

 

package com.jimmy.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;

public class NoBlockServerSocket {

    private Selector selector;

    private ByteBuffer byteBuffer=ByteBuffer.allocate(1024);

    public NoBlockServerSocket(int port) throws IOException {
        selector=Selector.open();
        ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();//创建nio通道
        serverSocketChannel.socket().bind(new InetSocketAddress(port));//创建基于nio通道的socket链接绑定
        serverSocketChannel.configureBlocking(false);//配置使通道不阻塞
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);//将通道绑定到选择器
    }

    public Selector getSelector() {
        return selector;
    }

    public void setSelector(Selector selector) {
        this.selector=selector;
    }

    public void listen() {

        try {
            for(;;) {

                int i=selector.select();//获取通道内关心事件的集合。
                if(i<1){
                    continue;
                }
                //Selector传回一组SelectionKeys
                Iterator<SelectionKey> iter=selector.selectedKeys().iterator();
                if(iter.hasNext()) {
                    SelectionKey selectionKey=iter.next();
                    //一个key被处理完成后,就都被从就绪关键字(ready keys)列表中除去
                    iter.remove();
                    process(selectionKey);
                }
                System.out.println(" loop " + new Date());
            }
        } catch(IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void process(SelectionKey selectionKey) throws IOException {
        System.out.println("selectionKey.isAcceptable()"+selectionKey.isAcceptable());
        System.out.println("selectionKey.isReadable()"+selectionKey.isReadable());
        System.out.println("selectionKey.isWritable()"+selectionKey.isWritable());
       
        if(selectionKey.isAcceptable()) {//获得客户端链接,并注册到选择器中,观察的动作有读写。
            ServerSocketChannel server=(ServerSocketChannel)selectionKey.channel();
            SocketChannel socketChannel=server.accept();
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
            System.out.println("accept:" + selectionKey.interestOps() + " " + selectionKey.readyOps());
        } else if(selectionKey.isReadable()) {//这个通道是一个可读的状态。进行读取操作
            SocketChannel channel=(SocketChannel)selectionKey.channel();
            int count=channel.read(byteBuffer);
            if(count > 0) {
                byteBuffer.flip();
                byte[] bbb=byteBuffer.array();
                System.out.println("i receive" + new String(bbb, 0, count));
                byteBuffer.clear();
            }
        } else if(selectionKey.isWritable()) {//这个通道是一个可以写的状态,进行写入的操作
            System.out.println("isWritable:" + selectionKey.interestOps());
            SocketChannel channel=(SocketChannel)selectionKey.channel();
            byteBuffer.clear();
            byteBuffer.put(new Date().toString().getBytes());
            byteBuffer.flip();
            channel.write(byteBuffer);
            channel.close();
            byteBuffer.clear();
        }
        System.out.println("\n\n\n");
    }

    public static void main(String[] args) {
        int port=8888;
        try {
            NoBlockServerSocket server=new NoBlockServerSocket(port);
            System.out.println("listening on " + port);
            server.listen();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

 

 

分享到:
评论

相关推荐

    一个java NIO的例子

    2. **缓冲区(Buffer)**:缓冲区是数据存储的容器,所有从通道读取的数据都会先被放入缓冲区,然后从缓冲区写入通道。Java NIO提供了字节、字符、短整型、整型、长整型、浮点型和双精度浮点型等类型的缓冲区。缓冲...

    实现java网络与nio例子

    这个例子包含了NIO在网络通信中的应用,包括服务器端(Server)和客户端(Client)的实现。 在Java NIO中,核心组件有通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。通道是数据传输的途径,如套接字...

    JAVA nio的一个简单的例子

    在这个“JAVA nio的一个简单的例子”中,我们将探讨如何使用Java NIO进行简单的服务器-客户端通信,并计算字符串的哈希值。 在传统的BIO模型中,每个连接都需要一个线程来处理,当并发连接数量增加时,系统会创建...

    NIO 服务器客户端例子

    1. **套接字通道(SocketChannel)**:客户端通过`SocketChannel.open()`创建通道,并用`socketChannel.connect(new InetSocketAddress(serverAddress, serverPort))`连接到服务器。 2. **缓冲区(Buffers)**:NIO...

    NIO socket编程小例子 加法服务器

    2. **Buffer**:缓冲区是NIO的核心组件,用于存储数据。在Java NIO中,有多种类型的Buffer,如ByteBuffer、CharBuffer等,它们都继承自抽象类Buffer。 3. **Selector**:选择器用于监听多个通道的事件,如连接、...

    socket编程例子

    在这个例子中,我们关注的是使用Non-blocking I/O(NIO)的Socket通信,这是一种提高性能和效率的方式,因为它允许单个线程处理多个连接。 在Java中,Socket接口代表了网络上的两个应用程序间的双向通信链路。而NIO...

    Netty 聊天 例子

    在本“Netty 聊天例子”中,我们将深入探讨如何利用 Netty 构建一个简单的聊天应用,这对于初学者来说是一个很好的起点。 **Netty 基础** Netty 的核心组件包括 Channel、Bootstrap、Pipeline 和 EventLoopGroup。...

    TestNetty 一个小例子

    5. **客户端连接**:Bootstrap 配置好 EventLoopGroup、SocketChannel 类型以及 ChannelInitializer 后,connect() 方法发起连接请求。 在 TestNetty 的源代码中,可能会包含一个简单的 Echo 服务示例,即客户端...

    Mina实现RPC的例子

    这个例子中的链接(http://blog.csdn.net/stevexk/archive/2008/07/23/2697907.aspx)提供了更详细的实现细节,包括具体的编码和解码逻辑,以及如何在Mina的过滤器和处理器中处理RPC请求。如果你需要深入学习,建议...

    一个NIO服务端,客户端的例子

    客户端则会创建Bootstrap实例,设置通道工厂,通常是NioSocketChannel。同样地,客户端也需要配置管道,其中包含一个ByteToMessageDecoder和一个ClientBusinessHandler,后者负责与服务器交互的逻辑。 在启动服务器...

    netty入门例子--(不是翻译官方文档)

    这个“netty入门例子”旨在帮助初学者理解Netty的基本用法和特性,而不是简单地翻译官方文档,它提供了几个开发模板,以便于深入理解Netty中的消息异步通信机制和TCP通信的封装。 首先,Netty的核心是它的异步模型...

    自己写的Java NIO 同步不阻塞IO操作

    描述中提到的"用nio想的一个不阻塞NIOSocket例子"可能是一个Java NIO的Socket通信示例,利用NIO的Channel和Selector来实现客户端和服务器之间的非阻塞通信。通常,NIO中的SocketChannel用于网络通信,Selector用于...

    非阻塞通信例子【nonblocking】示例

    2. **客户端**:通过`SocketChannel`建立连接,向服务器发送数据。 3. **数据读写**:服务器和客户端都会使用`ByteBuffer`作为缓冲区,用于数据的读写。在非阻塞模式下,`read()`和`write()`方法不会立即返回,而是...

    netty4服务端客户端实例

    2. **ServerSocketChannel**: 表示服务器端的套接字通道,用于监听客户端连接。 3. **ChannelHandler**: 处理网络事件的接口,你可以自定义多个处理器来处理不同类型的事件。 4. **ChannelPipeline**: 事件处理链,...

    用Netty5写一个简单的服务端和客户端.rar

    public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new MyServerHandler()); } }); b.bind(PORT).sync(); ``` 客户端使用Bootstrap来创建连接,同样配置ChannelHandler,但...

    netty基于protobuf的简单示例

    protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new ProtobufVarint32FrameDecoder()); p.addLast(new ProtobufDecoder(Greeting....

    netty 例子

    2. **Channel**:Channel 是 Netty 中的核心概念,代表了一个网络连接。它可以读取和写入数据,并提供了异步的 I/O 操作。例如,SocketChannel 代表了一个 TCP 连接,DatagramChannel 用于 UDP 协议。 3. **Event...

    socket 长连接 多线程 心跳包 包头包体

    socket 长连接 简单例子,适合初学的朋友,里面有多线程 实现的,包括心跳包,数据分为两部分传送,首先双方约定用一个4字节的数组告诉对方要传送数据的长度,然后在写入数据,这样长连接的时候,双方可以知道对方...

    咕泡学院_Tom_JavaVIP课程_深入分析Netty源码1

    2. **ChannelType**: Channel是Netty中表示网络连接的接口,这里选择了NioSocketChannel,适用于客户端的TCP连接。根据不同的协议和I/O模型,Netty提供了多种Channel实现,如NioServerSocketChannel用于服务器端TCP...

    Android MiNa 通讯实现

    这个例子将详细介绍如何在Android环境中实现MiNa进行文本传输。 ### 1. MiNa核心概念 MiNa基于Java的NIO(Non-blocking I/O)模型,提供了事件驱动、非阻塞I/O的网络通信库。主要包含以下几个核心组件: - **...

Global site tag (gtag.js) - Google Analytics