NIO笔记
来源:互联网 发布:通用网址和域名的区别 编辑:程序博客网 时间:2024/05/06 15:31
最近在研究NIO,在网上找了个实例:
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- 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;
- public class NIOServer {
-
- /*标识数字*/
- private int flag = 0;
- /*缓冲区大小*/
- private int BLOCK = 4096;
- /*接受数据缓冲区*/
- private ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
- /*发送数据缓冲区*/
- private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
- private Selector selector;
- public NIOServer(int port) throws IOException {
- // 打开服务器套接字通道
- ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
- // 服务器配置为非阻塞
- serverSocketChannel.configureBlocking(false);
- // 检索与此通道关联的服务器套接字
- ServerSocket serverSocket = serverSocketChannel.socket();
- // 进行服务的绑定
- serverSocket.bind(new InetSocketAddress(port));
- // 通过open()方法找到Selector
- selector = Selector.open();
- // 注册到selector,等待连接
- serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
- System.out.println("Server Start----8888:");
- }
- // 监听
- private void listen() throws IOException {
- while (true) {
- // 选择一组键,并且相应的通道已经打开
- selector.select();
- // 返回此选择器的已选择键集。
- Set<SelectionKey> selectionKeys = selector.selectedKeys();
- Iterator<SelectionKey> iterator = selectionKeys.iterator();
- while (iterator.hasNext()) {
- SelectionKey selectionKey = iterator.next();
- iterator.remove();
- handleKey(selectionKey);
- }
- }
- }
- // 处理请求
- private void handleKey(SelectionKey selectionKey) throws IOException {
- // 接受请求
- ServerSocketChannel server = null;
- SocketChannel client = null;
- String receiveText;
- String sendText;
- int count=0;
- // 测试此键的通道是否已准备好接受新的套接字连接。
- if (selectionKey.isAcceptable()) {
- // 返回为之创建此键的通道。
- server = (ServerSocketChannel) selectionKey.channel();
- // 接受到此通道套接字的连接。
- // 此方法返回的套接字通道(如果有)将处于阻塞模式。
- client = server.accept();
- // 配置为非阻塞
- client.configureBlocking(false);
- // 注册到selector,等待连接
- client.register(selector, SelectionKey.OP_READ);
- } else if (selectionKey.isReadable()) {
- // 返回为之创建此键的通道。
- client = (SocketChannel) selectionKey.channel();
- //将缓冲区清空以备下次读取
- receivebuffer.clear();
- //读取服务器发送来的数据到缓冲区中
- count = client.read(receivebuffer);
- if (count > 0) {
- receiveText = new String( receivebuffer.array(),0,count);
- System.out.println("服务器端接受客户端数据--:"+receiveText);
- client.register(selector, SelectionKey.OP_WRITE);
- }
- } else if (selectionKey.isWritable()) {
- //将缓冲区清空以备下次写入
- sendbuffer.clear();
- // 返回为之创建此键的通道。
- client = (SocketChannel) selectionKey.channel();
- sendText="message from server--" + flag++;
- //向缓冲区中输入数据
- sendbuffer.put(sendText.getBytes());
- //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位
- sendbuffer.flip();
- //输出到通道
- client.write(sendbuffer);
- System.out.println("服务器端向客户端发送数据--:"+sendText);
- client.register(selector, SelectionKey.OP_READ);
- }
- }
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- // TODO Auto-generated method stub
- int port = 8888;
- NIOServer server = new NIOServer(port);
- server.listen();
- }
- }
客户端
- 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.SocketChannel;
- import java.util.Iterator;
- import java.util.Set;
- public class NIOClient {
- /*标识数字*/
- private static int flag = 0;
- /*缓冲区大小*/
- private static int BLOCK = 4096;
- /*接受数据缓冲区*/
- private static ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
- /*发送数据缓冲区*/
- private static ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
- /*服务器端地址*/
- private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress(
- "localhost", 1111);
- public static void main(String[] args) throws IOException {
- // TODO Auto-generated method stub
- // 打开socket通道
- SocketChannel socketChannel = SocketChannel.open();
- // 设置为非阻塞方式
- socketChannel.configureBlocking(false);
- // 打开选择器
- Selector selector = Selector.open();
- // 注册连接服务端socket动作
- socketChannel.register(selector, SelectionKey.OP_CONNECT);
- // 连接
- socketChannel.connect(SERVER_ADDRESS);
- // 分配缓冲区大小内存
-
- Set<SelectionKey> selectionKeys;
- Iterator<SelectionKey> iterator;
- SelectionKey selectionKey;
- SocketChannel client;
- String receiveText;
- String sendText;
- int count=0;
- while (true) {
- //选择一组键,其相应的通道已为 I/O 操作准备就绪。
- //此方法执行处于阻塞模式的选择操作。
- selector.select();
- //返回此选择器的已选择键集。
- selectionKeys = selector.selectedKeys();
- //System.out.println(selectionKeys.size());
- iterator = selectionKeys.iterator();
- while (iterator.hasNext()) {
- selectionKey = iterator.next();
- if (selectionKey.isConnectable()) {
- System.out.println("client connect");
- client = (SocketChannel) selectionKey.channel();
- // 判断此通道上是否正在进行连接操作。
- // 完成套接字通道的连接过程。
- if (client.isConnectionPending()) {
- client.finishConnect();
- System.out.println("完成连接!");
- sendbuffer.clear();
- sendbuffer.put("Hello,Server".getBytes());
- sendbuffer.flip();
- client.write(sendbuffer);
- }
- client.register(selector, SelectionKey.OP_READ);
- } else if (selectionKey.isReadable()) {
- client = (SocketChannel) selectionKey.channel();
- //将缓冲区清空以备下次读取
- receivebuffer.clear();
- //读取服务器发送来的数据到缓冲区中
- count=client.read(receivebuffer);
- if(count>0){
- receiveText = new String( receivebuffer.array(),0,count);
- System.out.println("客户端接受服务器端数据--:"+receiveText);
- client.register(selector, SelectionKey.OP_WRITE);
- }
- } else if (selectionKey.isWritable()) {
- sendbuffer.clear();
- client = (SocketChannel) selectionKey.channel();
- sendText = "message from client--" + (flag++);
- sendbuffer.put(sendText.getBytes());
- //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位
- sendbuffer.flip();
- client.write(sendbuffer);
- System.out.println("客户端向服务器端发送数据--:"+sendText);
- client.register(selector, SelectionKey.OP_READ);
- }
- }
- selectionKeys.clear();
- }
- }
- }
0 0
- NIO笔记
- NIO 笔记
- NIO笔记
- Java Nio学习笔记
- NIO学习笔记
- NIO学习笔记(一)
- JAVA NIO 笔记
- NIO学习笔记1
- JAVA-NIO-个人笔记
- java nio 笔记
- Java NIO学习笔记
- Java NIO笔记 Channel
- [网络]NIO学习笔记
- Java Nio 笔记
- java NIO 学习笔记
- JAVA NIO的笔记
- NIO学习笔记一
- NIO学习笔记二
- 1.2 NSString字符串
- JVM内存分配与回收简述
- 1.3 封装
- position的四个属性值: relative ,absolute ,fixed,static
- makefile demo
- NIO笔记
- 1.4 继承和多态
- lintcode-366
- 迭代器-Collection
- hdu 3743 Frosh Week (归并排序·逆序数)
- 红帽子虚拟机非法关机后,显示网络已被禁用解决方法
- Linux常用命令记录
- TCP小练习2
- Java中对字符串的操作