socket IO流例子

一、BIO 阻塞IO 

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9000);
        while(true){
            Socket socket = serverSocket.accept();
            System.out.println("somebody connected");
            handler(socket);
            socket.close();
        }
    }

    public static void handler(Socket socket) {
        int value = 0;
        try {
            value = socket.getInputStream().read();
            while (value != -1) {
                System.out.println(value);
                value = socket.getInputStream().read();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

二、NIO 非阻塞IO

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;

public class NioSelectServer {
    static List<SocketChannel> channelList = new ArrayList<>();
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(9000));
        serverSocketChannel.configureBlocking(false);
        while(true){
            SocketChannel socketChannel = serverSocketChannel.accept();
            if(null != socketChannel){
                //someone connected
                socketChannel.configureBlocking(false);
                channelList.add(socketChannel);
            }

            for (SocketChannel channel : channelList) {
                ByteBuffer byteBuffer = ByteBuffer.allocate(100);
                int len = channel.read(byteBuffer);
                if(len == -1){
                    channelList.remove(channel);
                }else if(len !=0){
                    System.out.println(new String(byteBuffer.array()));
                }
            }
        }
    }
}

三、NIO Selector

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.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class NioSelectorServer {
    static List<SocketChannel> channelList = new ArrayList<>();

    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(9000));
        serverSocketChannel.configureBlocking(false);
        //打开selector,注册channel即创建epoll(create ctl )
        Selector selector = Selector.open();
        SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            //阻塞等待事件的触发
            selector.select();
            //获取所有触发的事件
            Set<SelectionKey> selectionKeys = selector.keys();
            Iterator<SelectionKey> iterator =  selectionKeys.iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                if(key.isAcceptable()){
                    ServerSocketChannel server = (ServerSocketChannel)key.channel();
                    SocketChannel socketChannel = server.accept();
                    if(null != socketChannel){
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector,SelectionKey.OP_READ);
                        System.out.println("连接成功");
                    }
                }else if(key.isReadable()){
                    SocketChannel socketChannel = (SocketChannel)key.channel();
                    ByteBuffer byteBuffer = ByteBuffer.allocate(128);
                    int len = socketChannel.read(byteBuffer);
                    if(len > 0){
                        System.out.println(new String(byteBuffer.array()));
                    }else if(len == -1){
                        System.out.println("disconnected");
                        socketChannel.close();
                    }
                }
            }
        }
    }
}

四、epoll模型

epoll模型由三个指令组成epoll_create、epoll_ctl、epoll_wait,分别表示创建描述符、注册描述符事件、阻塞等待事件触发

epoll的底层是一个红黑树存储描述符,在epoll_ctl的时候把描述符存到内核态空间,并设置一个回调任务,当该描述符有对应事件的时候,会把注册的对象和对应的事件写到待处理列表,然后epoll_wait会定时读取这个列表,有数据的话就会返回

特点:

1、epoll的数据是通过dmmp直接在用户态跟内核态共享内存,速度很快

2、epoll有两种模式,一种是数据没有读取完毕就会通知(会导致事件过多),第二种是只通知一次,需要把数据全读取完毕

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值