2.1Java 阻塞式io

Java 阻塞式io

执行流程

总体流程图
OIO:线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作完成。
一个连接一个线程
在这里插入图片描述

1.Server

  1. 创建连接(ServerSocketChannel)
  2. 开启端口(SocketAddress)并绑定bind()
  3. 循环监听
    1)等待请求连接serversocketchannel.accept() 【发生阻塞】
    2)每个SocketChannel开启线程读取数据。

2.Client

  1. 开启socketChannel
  2. 创建连接socketChannel.connect(地址,端口)
  3. 开始发送和接受数据。

代码

Server

public class Server {
    public static void main(String[] args) throws IOException {

//        开启Socket
        ServerSocketChannel serversocketchannel = ServerSocketChannel.open();
//        开启端口
        SocketAddress  socketAddress = new InetSocketAddress(8080);
//        监听8080 端口进来的tcp连接
        serversocketchannel.socket().bind(socketAddress);
//        开启循环监听
        while(true){
//            这里会阻塞,直到有请求连接
            SocketChannel socketChannel = serversocketchannel.accept();
//            开启新的线程来处理这个请求,然后while循环监听8080端口
            SocketHandler handler = new SocketHandler(socketChannel);
            new Thread(handler).start();
        }
    }
}

SocketHandler处理数据

public class SocketHandler implements Runnable{

    private SocketChannel socketChannel;
    public SocketHandler(SocketChannel socketChannel){
        this.socketChannel = socketChannel;
    }
    public void run() {
//      堆空间中分配缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        try {
//            将请求数据读入Buffer中
            int num ;
//            如果有数据
            while ((num = socketChannel.read(buffer))>0){
//                读取Buffer内容之前先flip一下
                // Buffer 切换为读模式
                buffer.flip();
//               加快读取速度
                byte[] bytes = new byte[num];
//                读取数据
                buffer.get(bytes);
                String result = new String (bytes,"UTF-8");
                System.out.println("收到请求:"+result);
//                回复客户端
//                warp用于存放在byte数组
                ByteBuffer writeBuffer = ByteBuffer.wrap(("我已经收到你的请求,你的请求内容是:" + result).getBytes());
                socketChannel.write(writeBuffer);
                buffer.clear();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

client

public class Client {

    public static void main(String[] args) {
        try {
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress("localhost",8080));
//            发送请求
            ByteBuffer buffer = ByteBuffer.wrap("test".getBytes());
            socketChannel.write(buffer);
//            获取server响应
            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
            int num ;
            if((num = socketChannel.read(readBuffer))> 0 ){
                readBuffer.flip();
                byte[] result = new byte[num];
                readBuffer.get(result);
                String  demo = new String(result,"UTF-8");
                System.out.println("返回值:"+demo);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

结果展示和分析

运行结构
Server
在这里插入图片描述
client
在这里插入图片描述

阻塞io的缺点

  1. 每次连接都要新开线程(accept()方法开线程处理。)
  2. accept() 是一个阻塞操作,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值