`
落叶留步
  • 浏览: 53302 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

1.java nio 网络编程 Server端

 
阅读更多

    最近一段时间看了下java nio,对于它的实际用途还有待继续研究,也看了网上很多人的文章博客等,收益颇多,但是还是自己动手才能知道自己是否真的会写了,会写与是否理解nio工作机制还有一定距离。我又不是一个理论派,主要还是讲究实战的,好,废话不多说,直接准备动作写。

    首先你需要了解几个nio网络编程中会用到的组件(类):

    1.ByteBuffer

    2.Selector

    3.ServerSocketChannel

    4.SocketChannel

    5.SelectionKey

    

    说一下nio server的整体实现思路:

    打开Selector--》 打开ServerSocketChannel --> 配置ServerSocketChannel是否阻塞 --》 绑定ServerSocketChannel到某个主机以及端口 --》给ServerSocketChannel注册一个Selector --》 ServerSocketChannel监听accept事件 --》 客户端连接后获取SocketChannel --》 响应SocketChannel上的read/write事件

 

    我写的可能和网络上一些人写的稍微有点不太一样,这也没办法,网络上打开10篇nio相关文章,有好几篇都是一样的,你抄我,我抄你的。个个图文并茂,个个都是架构师,分析reactor设计模式,多路复用,高性能,讲的头头是道,不过这和我没什么关系,我体会不到,应该是我太菜了。所以还是来点简单的,基础打好,总归不会有害处。

 

    下面是具体实现代码:把这个代码拷贝到你的ide中,然后运行,用tcp连接工具,比如putty,cmd也行,不过cmd没有那么好用。有两个例子,第一个是只能少量字符传输,第二个支持大文本传输。

 

    demo1:

package com.govert.project;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
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.Iterator;
import java.util.Random;
import java.util.Set;

/**
 * 少量字符传输
 */
public class NioServer {

    public static void main(String[] args) throws IOException {
        // read and write byte buffer
        ByteBuffer rb = ByteBuffer.allocate(1024);
        ByteBuffer wb = ByteBuffer.allocate(1024);

        // listen hostname and port
        String hostname = "127.0.0.1";
        int port = 9000;

        // open Selector & check
        Selector selector = Selector.open();
        if (selector.isOpen()) {
            System.err.println("selector open success.");
        }

        // open ServerSocketChannel & check
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        if (serverSocketChannel.isOpen()) {
            System.err.println("serverSocketChannel open success.");
        }

        // ServerSocketChannel config non-block & bind hostname and port
        serverSocketChannel.configureBlocking(false);
        // serverSocketChannel.socket().bind(new InetSocketAddress(hostname, port));// old way bind
        serverSocketChannel.bind(new InetSocketAddress(hostname, port));// 1.7+

        // ServerSocketChannel register selector
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        // handle event loop
        while (true) {

            selector.select();

            Set<SelectionKey> keys = selector.selectedKeys();
            Iterator<SelectionKey> kit = keys.iterator();
            while (kit.hasNext()) {
                SelectionKey key = kit.next();

                // read event
                if (key.isReadable()) {
                    SocketChannel socketChannel = (SocketChannel) key.channel();

                    rb.clear();
                    socketChannel.read(rb);
                    rb.flip();
                    System.err.println("client request data: " + new String(rb.array(), 0, rb.limit(), "utf-8"));
                    //
                    key.interestOps(SelectionKey.OP_WRITE);
                }
                // write event
                else if (key.isWritable()) {
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    String resp = "server response data: " + new Random().nextInt(1000) + 1 + "\r\n";
                    wb.clear();
                    wb.put(resp.getBytes("utf-8"));
                    wb.flip();
                    socketChannel.write(wb);

                    //
                    key.interestOps(SelectionKey.OP_READ);
                }
                // accept event
                else if (key.isAcceptable()) {
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                }
            }

            // clear keys
            keys.clear();
        }
    }

}
 

  

    demo2:

package com.govert.project;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;

/**
 * 大文本传输
 */
public class NioServer {

    public static void main(String[] args) throws IOException {
        // read and write byte buffer
        ByteBuffer rb = ByteBuffer.allocate(1024);
        ByteBuffer wb = ByteBuffer.allocate(1024);

        // listen hostname and port
        String hostname = "127.0.0.1";
        int port = 9000;

        // open Selector & check
        Selector selector = Selector.open();
        if (selector.isOpen()) {
            System.err.println("Selector open success.");
        }

        // open ServerSocketChannel & check
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        if (serverSocketChannel.isOpen()) {
            System.err.println("ServerSocketChannel open success.");
        }

        // ServerSocketChannel config non-block & bind hostname and port
        serverSocketChannel.configureBlocking(false);
        // serverSocketChannel.socket().bind(new InetSocketAddress(hostname, port));// old way bind
        serverSocketChannel.bind(new InetSocketAddress(hostname, port));// 1.7+

        // ServerSocketChannel register selector
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        // handle event loop
        while (true) {

            selector.select();

            Set<SelectionKey> keys = selector.selectedKeys();
            Iterator<SelectionKey> kit = keys.iterator();
            while (kit.hasNext()) {
                SelectionKey key = kit.next();

                // read event
                if (key.isReadable()) {
                    SocketChannel socketChannel = (SocketChannel) key.channel();

                    // large text
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    StringBuilder sb = new StringBuilder();
                    while (true) {
                        if (socketChannel.read(rb) < 1 && rb.hasRemaining()) break;
                        rb.flip();
                        baos.write(rb.array(), 0, rb.limit());
                        rb.clear();
                    }
                    //
                    System.err.println("client request data: " + new String(baos.toByteArray(), 0, baos.size(), "utf-8"));
                    //
                    key.interestOps(SelectionKey.OP_WRITE);
                }
                // write event
                else if (key.isWritable()) {
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    // large response
                    StringBuilder sb = new StringBuilder();
                    for (int i = 1; i < 1001; i++) {
                        sb.append("server respnse data: 第" + i + "条响应结果.\r\n");
                    }
                    byte[] bytes = sb.toString().getBytes("utf-8");
                    int length = bytes.length;
                    int loop = (length + 1023) / 1024;
                    int lastLoop = loop - 1;
                    int len;
                    for (int i = 0; i < loop; i++) {
                        if (i == lastLoop) len = length - i * 1024;
                        else len = 1024;
                        wb.put(bytes, i * 1024, len);
                        wb.flip();
                        socketChannel.write(wb);
                        wb.clear();
                    }

                    //
                    key.interestOps(SelectionKey.OP_READ);
                }
                // accept event
                else if (key.isAcceptable()) {
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                }
            }

            // clear keys
            keys.clear();
        }
    }

}

 

 

分享到:
评论

相关推荐

    nioserver.zip_NIO_event driven java_java nio_java nioserv_nioser

    标题中的“nioserver.zip_NIO_event driven java_java nio_java nioserv_nioser”表明这是一个关于Java NIO的服务器实现,且是基于事件驱动模式的。事件驱动编程是一种设计模式,它允许程序对特定事件做出响应,而...

    nioserver.rar_NIO_java nio

    NIO(Non-blocking Input/Output)是Java编程语言中的一种I/O模型,它与传统的阻塞I/O(BIO)模型相比,具有更高的性能和更灵活的架构。NIO在Java 1.4版本中引入,全称为New Input/Output,它的核心在于“非阻塞”二...

    基于java NIO的socket通信demo

    首先,我们来看`NioServer.java`。这个文件中包含了一个基于NIO的服务器端实现。服务器的核心组件是`Selector`,它允许一个单独的线程监听多个套接字通道的状态变化。当客户端发起连接请求时,服务器会注册`...

    NioSocket,包括server端和client端

    NioSocket是一个基于Java NIO(非阻塞I/O)技术实现的网络通信框架,它包含服务器端(Server)和客户端(Client)两部分。在Java编程中,NIO(New Input/Output)提供了一种不同于传统IO模型的I/O操作方式,其核心...

    java多线程Client/Server程序

    在本程序中,`ChatServer.java` 和 `ChatClient.java` 文件可能分别代表了服务器端和客户端的核心代码。下面将详细讨论Java多线程在Client/Server程序中的应用及其相关知识点。 1. **Java多线程** - **线程的创建*...

    JAVA-NIO程序设计完整实例

    - **网络通信优化**: 在网络编程中,通过NIO的非阻塞模式,可以更有效地处理网络数据的读写。 ### 5. 示例代码片段 ```java Selector selector = Selector.open(); ServerSocketChannel server = ...

    Java_qq_Server.rar_Java_qq_Server_Socket网络编程_java 网络编程_即时通信_网络通信

    Java QQ Server 是一个基于Java Socket网络编程实现的即时通信系统,它主要用于建立网络通信连接,实现客户端与服务器之间的数据交互。在Java编程中,Socket是网络通信的核心组件,它允许两个网络应用程序通过TCP...

    【IT十八掌徐培成】Java基础第27天-04.NIO-Selector-Server-Client.zip

    Java NIO(New IO)是Java 1.4版本引入的一个新模块,全称为Non-blocking Input/Output,它提供了一种不同于传统IO的I/O操作...通过观看视频和动手实践,可以深入掌握Java NIO的核心概念,提高处理并发网络编程的能力。

    实现java网络与nio例子

    Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 ...这个"网络与nio"的压缩包文件很可能包含了服务器端和客户端的完整代码示例,可以帮助我们深入理解并实践Java NIO在网络编程中的应用。

    第十四章 Java网络编程.rar_java 课件_java网络_java网络编程

    Java NIO(New I/O)提供了一种新的I/O模型,可以提高网络编程的效率。NIO使用选择器(Selector)和通道(Channel)进行数据传输,可以同时处理多个连接,尤其适用于高并发场景。 7. **网络安全**: Java还提供了...

    java nio聊天室源码

    Java NIO(New IO)是Java 1.4版本引入的一种新的I/O API,它提供了非阻塞I/O操作的能力,极大地提升了Java在...通过分析和学习这个源码,开发者可以深入理解Java NIO的工作原理,并将其应用于实际的网络编程项目中。

    ServerBootstrap实现nio.rar_NIO_ServerBootstrap_heart8w9_java nio

    在Java网络编程中,`ServerBootstrap` 是一个用于构建高性能异步网络应用的工具,它主要用在NIO(Non-blocking I/O)模式下。NIO(非阻塞I/O)是Java提供的一种I/O模型,它允许一个线程处理多个输入/输出流,与传统...

    Java NIO实现多个客户端之间的消息互发,客户端与服务器完整代码

    Java NIO(Non-blocking Input/...在实际开发中,Java NIO的使用需要对多线程、网络编程以及NIO API有深入的理解。通过这种方式构建的系统可以高效地处理大量并发连接,非常适合于聊天、游戏等实时性要求高的应用场景。

    JAVA网络编程基础案例

    网络是计算机之间通过通信协议连接的集合,而Java提供了一套丰富的API来支持网络编程,主要包括java.net和java.nio包。在这些包中,Socket和ServerSocket是核心类,它们分别代表了客户端和服务端的连接。 1. **...

    nio socket编程java代码示例,客户端发送消息,服务端接收

    本示例将详细解析如何使用Java的非阻塞I/O(NIO)实现Socket通信,包括客户端发送消息和服务器端接收消息的过程。 首先,理解NIO(Non-blocking Input/Output)的概念至关重要。NIO与传统的IO模型不同,它提供了对...

    java网络编程 源代码

    Java网络编程是Java开发中的重要领域,特别是在分布式系统、服务器端应用和互联网服务开发中扮演着核心角色。孙卫琴的这部作品深入浅出地介绍了Java进行网络编程的基础知识和实践技巧,对于初学者来说是一份很好的...

    网络编程小测试

    本测试聚焦于Java语言的网络编程,其中包含了两个关键文件:Server.java和Client.java,这通常代表了一个简单的服务器-客户端架构。 1. **Java网络编程基础**:Java提供了丰富的API来处理网络通信,主要在`java.net...

    Java socket网络编程的基础示例

    Java Socket网络编程是Java平台中实现网络通信的核心技术,它基于传输层协议TCP和UDP,为应用程序提供了低级别的、原始的比特流服务。本基础示例将深入探讨这两种协议下的Socket编程。 首先,TCP(Transmission ...

    Java NIO原理解析

    Java NIO,即Non-Blocking I/O,是Java在JDK 1.4引入的一套新的I/O API,旨在提供一种更加高效的方式来处理I/O操作,尤其是对于网络编程和高并发场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器...

    java NIO 开发技术

    总的来说,Java NIO通过非阻塞I/O和选择器机制,实现了更加高效和可扩展的网络编程模型,特别适合处理大量并发连接的情况,如Web服务器、分布式系统等。理解和掌握NIO的原理和使用,对于优化高性能服务器端程序具有...

Global site tag (gtag.js) - Google Analytics