Java TCP NIO Example

Server端:

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;

/**
 * Create by leon on 2017/4/7
 */
public class Server {

    public static void main(String[] args) throws IOException {
        //打开事件监听
        Selector selector = Selector.open();
        //打开通道
        ServerSocketChannel ssc = ServerSocketChannel.open();
        //绑定监听端口,通过socket
        ssc.socket().bind(new InetSocketAddress(9527));
        //设置为非阻塞
        ssc.configureBlocking(false);
        //注册连接事件
        ssc.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
            int keys = selector.select(1000);
            if (keys > 0) { //有新的事件
                for (SelectionKey key : selector.selectedKeys()) {
                    if (key.isAcceptable()) {
                        //获取ServerSocketChannel
                        ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                        //获取SocketChannel
                        SocketChannel socketChannel = channel.accept();
                        if (socketChannel == null) {
                            continue;
                        }
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    } else if (key.isReadable()) {
                        //定义Buffer
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        //获取SocketChannel
                        SocketChannel socketChannel = (SocketChannel) key.channel();
                        //将数据读入buffer
                        socketChannel.read(byteBuffer);
                        //将buffer转成byte数组
                        byte[] array = byteBuffer.array();
                        String msg = new String(array).trim();
                        System.out.println("Receive Msg:" + msg);
                        if ("exit".equalsIgnoreCase(msg)) {
                            socketChannel.close();
                            ssc.close();
                            selector.close();
                            System.exit(0);
                        }
                        //获取发送消息用的buffer,wrap方法
                        ByteBuffer out = ByteBuffer.wrap(msg.getBytes());
                        //写入channel
                        socketChannel.write(out);
                    }
                }
                //注意这里要移除键
                selector.selectedKeys().clear();
            }
        }
    }
}

Client端:

import org.apache.commons.lang.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

/**
 * Create by leon on 2017/4/7
 */
public class Client {

    public static void main(String[] args) throws IOException {
        //打开事件监听
        Selector selector = Selector.open();
        //获取SocketChannel
        SocketChannel socketChannel = SocketChannel.open();
        //设置连接到服务器IP和端口
        socketChannel.connect(new InetSocketAddress("127.0.0.1", 9527));
        //设置非阻塞
        socketChannel.configureBlocking(false);
        //注册连接事件
        socketChannel.register(selector, SelectionKey.OP_CONNECT);
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            if (socketChannel.isConnected()) {  //先连接上,才能发送消息
                String command = in.readLine();
                socketChannel.write(ByteBuffer.wrap(command.getBytes()));
                if (StringUtils.isNotBlank(command) && "exit".equalsIgnoreCase(command)) {
                    in.close();
                    selector.close();
                    socketChannel.close();
                    System.exit(0);
                }
            }
            int keys = selector.select(1000);
            if (keys > 0) {
                for (SelectionKey key : selector.selectedKeys()) {
                    if (key.isConnectable()) {  //连接上
                        //获取SocketChannel
                        SocketChannel channel = (SocketChannel) key.channel();
                        channel.configureBlocking(false);
                        channel.register(selector, SelectionKey.OP_READ);
                        channel.finishConnect();
                    } else if (key.isReadable()) {
                        //定义Buffer
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        //获取SocketChannel
                        SocketChannel channel = (SocketChannel) key.channel();
                        //读到buffer中
                        channel.read(byteBuffer);
                        //转为字节数组
                        byte[] array = byteBuffer.array();
                        String msg = new String(array).trim();
                        System.out.println("Receive From Server:" + msg);
                    }
                }
                //注意这里要移除键
                selector.selectedKeys().clear();
            }
        }
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值