java NIO入门【原】

server

package com.server;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class Server {
    
    public static void main(String[] args) throws Exception {
        //新建TCP服务端
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //绑定TCP端口
        serverSocketChannel.socket().bind(new InetSocketAddress(9999));
        //配置成"非阻塞"
        serverSocketChannel.configureBlocking(false);
        while (true) {
            //允许接收TCP链接
            SocketChannel socketChannel = serverSocketChannel.accept();
            //当有TCP连接上来时,获取到的就不为空
            if (socketChannel != null) {
                //写英文数据"生命不步,战斗不息"
                String newData = System.currentTimeMillis() + ": Cease to struggle and you cease to live .";
                //开辟缓存
                ByteBuffer buf = ByteBuffer.allocate(1024);
                //重置,准备写入数据到缓存
                buf.clear();
                //真正写入数据到缓存
                buf.put(newData.getBytes());
                //准备从缓存读取数据
                buf.flip();
                //如果读到数据有剩余
                while (buf.hasRemaining()) {
                    //真正从缓存读取数据,并写入到通道中
                    socketChannel.write(buf);
                }
            }
        }
    }
}

client(默认非阻塞)

package com.client;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class client {
    public static void main(String[] args) throws Exception {
        //新建TCP服务端
        SocketChannel socketChannel = SocketChannel.open();
        //设置超时时间3秒,特别声明:这里浪费了大量时间研究和百度,只有正常的Socket的超时时间才有效,其实本处设置无效
        //http://blog.csdn.net/d8111/article/details/45249783
        socketChannel.socket().setSoTimeout(3000);
        //链接到本地的9999端口
        socketChannel.connect(new InetSocketAddress("localhost", 9999));
        //开辟缓存
        ByteBuffer buf = ByteBuffer.allocate(1024);
        //重置,准备写入数据到缓存
        buf.clear();
        //真正从通道读取数据到缓存
        int bytesRead = socketChannel.read(buf);
        //准备从缓存读取数据
        buf.flip();
        //如果读到数据有剩余
        while (buf.hasRemaining()) {
            //取一个字节
            byte b = (byte) (buf.get());
            //转成一个字符
            System.out.print((char) b);
        }
        //关闭通道
        socketChannel.close();
    }
}

client(手动配置阻塞)

package com.client;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class client {
    public static void main(String[] args) throws Exception {
        //新建TCP服务端
        SocketChannel socketChannel = SocketChannel.open();
        //设置超时时间3秒,特别声明:这里浪费了大量时间研究和百度,只有正常的Socket的超时时间才有效,其实设置本处无效
        //参考: http://blog.csdn.net/d8111/article/details/45249783
        //oracle bug id : http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4614802  JDK-4614802 : setSoTimeout does not work with nio SocketChannel
        socketChannel.socket().setSoTimeout(3000);
        //设置为非阻塞模式,默认阻塞
        socketChannel.configureBlocking(false);
        //链接到本地的9999端口
        socketChannel.connect(new InetSocketAddress("localhost", 9999));
        //当设置成非阻塞时,即异步时,需要先判断连接是否未定的,是否即将发 生的
        if (socketChannel.isConnectionPending()) {  
            //如果即将发生连接,那么就等待连接建立完成,不然极有可能报java.nio.channels.NotYetConnectedException
            socketChannel.finishConnect(); 
        }
            
        //开辟缓存
        ByteBuffer buf = ByteBuffer.allocate(1024);
        //重置,准备写入数据到缓存
        buf.clear();
        //真正从通道读取数据到缓存
        int bytesRead = socketChannel.read(buf);
        //准备从缓存读取数据
        buf.flip();
        //如果读到数据有剩余
        while (buf.hasRemaining()) {
            //取一个字节
            byte b = (byte) (buf.get());
            //转成一个字符
            System.out.print((char) b);
        }
        //关闭通道
        socketChannel.close();
    }
}
原文地址:https://www.cnblogs.com/whatlonelytear/p/7264382.html