`
隐形的翅膀
  • 浏览: 496979 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

基于Java NIO的Socket通信

 
阅读更多
Java NIO模式的Socket通信,是一种同步非阻塞IO设计模式,它为Reactor模式实现提供了基础。

下面看看,Java实现的一个服务端和客户端通信的例子。

NIO模式的基本原理描述如下:

服务端打开一个通道(ServerSocketChannel),并向通道中注册一个选择器(Selector),这个选择器是与一些感兴趣的操作的标识(SelectionKey,即通过这个标识可以定位到具体的操作,从而进行响应的处理)相关联的,然后基于选择器(Selector)轮询通道(ServerSocketChannel)上注册的事件,并进行相应的处理。

客户端在请求与服务端通信时,也可以向服务器端一样注册(比服务端少了一个SelectionKey.OP_ACCEPT操作集合),并通过轮询来处理指定的事件,而不必阻塞。

下面的例子,主要以服务端为例,而客户端只是简单地发送请求数据和读响应数据。

服务端实现,代码如下所示:
    package org.shirdrn.java.communications.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.Iterator;  
    import java.util.Set;  
    import java.util.logging.Logger;  
      
    /** 
     * NIO服务端 
     *  
     * @author shirdrn 
     */  
    public class NioTcpServer extends Thread {  
      
        private static final Logger log = Logger.getLogger(NioTcpServer.class.getName());  
        private InetSocketAddress inetSocketAddress;  
        private Handler handler = new ServerHandler();  
          
        public NioTcpServer(String hostname, int port) {  
            inetSocketAddress = new InetSocketAddress(hostname, port);  
        }  
          
        @Override  
        public void run() {  
            try {  
                Selector selector = Selector.open(); // 打开选择器  
                ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 打开通道  
                serverSocketChannel.configureBlocking(false); // 非阻塞  
                serverSocketChannel.socket().bind(inetSocketAddress);  
                serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); // 向通道注册选择器和对应事件标识  
                log.info("Server: socket server started.");  
                while(true) { // 轮询  
                    int nKeys = selector.select();  
                    if(nKeys>0) {  
                        Set<SelectionKey> selectedKeys = selector.selectedKeys();  
                        Iterator<SelectionKey> it = selectedKeys.iterator();  
                        while(it.hasNext()) {  
                            SelectionKey key = it.next();  
                            if(key.isAcceptable()) {  
                                log.info("Server: SelectionKey is acceptable.");  
                                handler.handleAccept(key);  
                            } else if(key.isReadable()) {  
                                log.info("Server: SelectionKey is readable.");  
                                handler.handleRead(key);  
                            } else if(key.isWritable()) {  
                                log.info("Server: SelectionKey is writable.");  
                                handler.handleWrite(key);  
                            }  
                            it.remove();  
                        }  
                    }  
                }  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
          
        /** 
         * 简单处理器接口 
         *  
         * @author shirdrn 
         */  
        interface Handler {  
            /** 
             * 处理{@link SelectionKey#OP_ACCEPT}事件 
             * @param key  
             * @throws IOException 
             */  
            void handleAccept(SelectionKey key) throws IOException;  
            /** 
             * 处理{@link SelectionKey#OP_READ}事件 
             * @param key  
             * @throws IOException 
             */  
            void handleRead(SelectionKey key) throws IOException;  
            /** 
             * 处理{@link SelectionKey#OP_WRITE}事件 
             * @param key  
             * @throws IOException 
             */  
            void handleWrite(SelectionKey key) throws IOException;  
        }  
          
        /** 
         * 服务端事件处理实现类 
         *  
         * @author shirdrn 
         */  
        class ServerHandler implements Handler {  
      
            @Override  
            public void handleAccept(SelectionKey key) throws IOException {  
                ServerSocketChannel serverSocketChannel = (ServerSocketChannel)key.channel();  
                SocketChannel socketChannel = serverSocketChannel.accept();  
                log.info("Server: accept client socket " + socketChannel);  
                socketChannel.configureBlocking(false);  
                socketChannel.register(key.selector(), SelectionKey.OP_READ);  
            }  
      
            @Override  
            public void handleRead(SelectionKey key) throws IOException {  
                ByteBuffer byteBuffer = ByteBuffer.allocate(512);  
                SocketChannel socketChannel = (SocketChannel)key.channel();  
                while(true) {  
                    int readBytes = socketChannel.read(byteBuffer);  
                    if(readBytes>0) {  
                        log.info("Server: readBytes = " + readBytes);  
                        log.info("Server: data = " + new String(byteBuffer.array(), 0, readBytes));  
                        byteBuffer.flip();  
                        socketChannel.write(byteBuffer);  
                        break;  
                    }  
                }  
                socketChannel.close();  
            }  
      
            @Override  
            public void handleWrite(SelectionKey key) throws IOException {  
                ByteBuffer byteBuffer = (ByteBuffer) key.attachment();  
                byteBuffer.flip();  
                SocketChannel socketChannel = (SocketChannel)key.channel();  
                socketChannel.write(byteBuffer);  
                if(byteBuffer.hasRemaining()) {  
                    key.interestOps(SelectionKey.OP_READ);  
                }  
                byteBuffer.compact();  
            }  
        }  
      
        public static void main(String[] args) {  
            NioTcpServer server = new NioTcpServer("localhost", 1000);  
            server.start();  
        }  
    }  


客户端实现,代码如下所示:

import java.io.IOException;  
import java.net.InetSocketAddress;  
import java.nio.ByteBuffer;  
import java.nio.channels.SocketChannel;  
import java.util.logging.Logger;  
  
/** 
 * NIO客户端 
 *  
 * @author shirdrn 
 */  
public class NioTcpClient {  
  
    private static final Logger log = Logger.getLogger(NioTcpClient.class.getName());  
    private InetSocketAddress inetSocketAddress;  
      
    public NioTcpClient(String hostname, int port) {  
        inetSocketAddress = new InetSocketAddress(hostname, port);  
    }  
      
    /** 
     * 发送请求数据 
     * @param requestData 
     */  
    public void send(String requestData) {  
        try {  
            SocketChannel socketChannel = SocketChannel.open(inetSocketAddress);  
            socketChannel.configureBlocking(false);  
            ByteBuffer byteBuffer = ByteBuffer.allocate(512);  
            socketChannel.write(ByteBuffer.wrap(requestData.getBytes()));  
            while (true) {  
                byteBuffer.clear();  
                int readBytes = socketChannel.read(byteBuffer);  
                if (readBytes > 0) {  
                    byteBuffer.flip();  
                    log.info("Client: readBytes = " + readBytes);  
                    log.info("Client: data = " + new String(byteBuffer.array(), 0, readBytes));  
                    socketChannel.close();  
                    break;  
                }  
            }  
  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
      
    public static void main(String[] args) {  
        String hostname = "localhost";  
        String requestData = "Actions speak louder than words!";  
        int port = 1000;  
        new NioTcpClient(hostname, port).send(requestData);  
    }  
}  
分享到:
评论

相关推荐

    基于java NIO的socket通信demo

    在这个“基于java NIO的socket通信demo”中,我们将探讨如何使用NIO进行服务器和客户端的Socket通信,并解决通信过程中的字符集乱码问题。 首先,我们来看`NioServer.java`。这个文件中包含了一个基于NIO的服务器端...

    java nio 实现socket

    基于Java NIO的Socket通信流程大致如下: 1. **创建ServerSocketChannel**:服务器端首先需要创建一个`ServerSocketChannel`,用于监听客户端的连接请求。 2. **创建Selector**:创建一个`Selector`对象,用于监听`...

    java NIO socket聊天

    在Java NIO中,数据的读写都是基于缓冲区进行的,这样可以避免不必要的数据拷贝,提高I/O操作的效率。 此外,Java NIO还引入了`Pipe`和`FileChannel`等特性,使得进程间通信和文件操作也变得更加灵活。`Pipe`允许两...

    java基于nio的socket通信.rar

    Java NIO(New IO)是Java 1.4...总的来说,Java NIO的Socket通信结合了非阻塞I/O和多路复用,为开发高性能、可扩展的网络应用提供了强大的工具。通过理解和实践这些概念,开发者可以创建出更加灵活和高效的网络服务。

    默蓝网络通信测试工具(NIOSocket工具)支持TCP/IP和HTTP通信-网络通信开发人员必备

    总的来说,"默蓝网络通信测试工具(NIOSocket工具)"凭借其对TCP/IP和HTTP通信的支持,以及Java NIO Socket编程的优势,为网络通信开发人员提供了全面的测试解决方案,是进行网络通信开发和优化的得力助手。...

    NioSocket,包括server端和client端

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

    JAVA NIO 异步通信模板服务端

    总之,JAVA NIO异步通信模板服务端是利用Java NIO库实现的高效并发服务,通过非阻塞I/O和选择器机制,可以轻松处理大量并发连接,同时保持较低的资源消耗。在实际开发中,这样的模板可以作为基础,根据具体需求进行...

    nio.rar_Java socketA_java nio_java socket a

    标题中的“Java socketA_java nio_java socket a”可能是指使用Java NIO实现的Socket通信,这里的"A"可能是表示"Advanced"或"Alternative",意味着比传统的阻塞I/O模型更为高级或替代方案。 在Java Socket API中,...

    socket通信NIO代理模式demo实例

    Socket通信在IT行业中是网络编程的基础,特别是在Java领域,它提供了服务器与客户端间进行数据交换的接口。NIO(Non-blocking I/O)是Java提供的一个高效I/O模型,相较于传统的IO模型,NIO具有非阻塞、多路复用等...

    nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio

    Java NIO(New IO)是Java 1.4版本引入的一个新特性,它为Java应用程序提供了非阻塞I/O操作的能力,与传统的IO模型(基于流的I/O和基于缓冲区的I/O)相比,NIO具有更高的效率和灵活性。在Java NIO中,数据是以通道...

    Java Socket学习---nio实现阻塞多线程通信

    在Java编程领域,Socket是网络通信的基础,它允许两个或多个应用程序通过TCP/IP协议进行数据交换。本篇文章将深入探讨如何使用Java NIO(非阻塞I/O)来实现阻塞多线程通信,这对于高性能服务器端应用尤其重要。我们...

    Nio非阻塞socket通信demo

    在这个“Nio非阻塞socket通信demo”中,我们可以深入理解NIO在Socket通信中的应用。 1. **Java NIO基础** - **通道(Channels)**:NIO的核心概念之一,通道是数据读写的目标或来源,如文件通道、套接字通道等。...

    C#和java 之间基于Socket的通信

    以上知识点涵盖了Java和C#之间基于Socket通信的基础知识,实际开发中可能还需要结合具体的应用场景进行更深入的设计和优化。在SocketTest.rar、JavaSocketTest.rar文件中,可能包含了示例代码和运行指南,readme.txt...

    java nio 通信服务器、客户端完整例子

    用java编写的nio通信的例子,nio是io编程的新版本,比io较流行。同时本例子是适用socket通信的。可以在此基础上,添加您的个人应用。本例子适用于:java通信的学习者,android平台通信的学习者。

    java socket 大文件传输,快速传输(包的分片,组装)源码

    总的来说,Java Socket大文件传输涉及到网络通信的基础原理,如TCP和UDP协议,以及提高效率和性能的技术,如文件分片、组装和NIO。通过理解并应用这些知识点,开发者能够构建出高效、可靠的文件传输系统。对于希望...

    一般Socket客户端与Mina NIO Socket客户端对比示例

    在IT行业中,网络编程是不可或缺的一部分,而Socket通信则是实现网络连接的基础。本文将通过一个对比实例,探讨一般Socket客户端与Mina NIO (Non-blocking I/O) Socket客户端的差异和特点,帮助开发者理解这两种技术...

    java Socket通信实现

    - Java NIO(New I/O)库提供了非阻塞的Socket通信方式,提高了高并发场景下的性能。 - `java.nio.channels.SocketChannel`和`java.nio.channels.ServerSocketChannel`是NIO中的Socket实现。 9. **SSL/TLS安全套...

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

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

    基于Java的源码-Java Socket通信实现.zip

    Java Socket通信实现是一种在两台计算机之间...以上是对"基于Java的源码-Java Socket通信实现.zip"中涉及的知识点的详细说明。通过学习和实践这些概念,开发者可以更好地理解和掌握Java网络编程,实现各种网络应用。

Global site tag (gtag.js) - Google Analytics