socket基础 和 io模型

一、socket简介

  1. socket定义:

    socket套接字是两台主机之间进行网络通信的基础,是实现TCP/IP网络通信的最基本的操作单元。

  2. socket网络通信流程描述

    • 服务器首先创建ServerSocket套接字绑定端口,并实时监听客户端连接。

    • 客户端创建Socket套接字绑定服务器ip和端口号,绑定成功后即可利用socket获取的输出流发送信息。

    • 服务端监听到客户端的连接并且收到发送的信息,通过输出流响应客户端。

      流程图

      请添加图片描述

  3. 代码实现

    服务器代码:

public class Server {

    public static void main(String[] args) throws IOException {
        //1. 创建线程池,当客户端连接时,使用一个线程与客户端通信
        ExecutorService executorService = Executors.newCachedThreadPool();

        //2. 创建ServerSocket对象,绑定本地端口
        ServerSocket serverSocket = new ServerSocket(9988);

        while (true) {
            //3. 循环监听客户端
            Socket socket = serverSocket.accept();

            //4. 当监听到客户端连接时,开启新的线程处理当前连接
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("==========>>>线程ID:" + Thread.currentThread().getId()
                                + "; 线程名称:" + Thread.currentThread().getName());
                        InputStream inputStream = socket.getInputStream();

                        //取出socket字节流中数据通用的方式
                        int count = 0;
                        while (count == 0){
                            count = inputStream.available();
                        }

                        //取出连接中输入流,获取消息
                        byte[] bytes = new byte[count];
                        inputStream.read(bytes);
                        System.out.println("客户端消息:" + new String(bytes, 0, count, StandardCharsets.UTF_8));

                        //连接中取出输出流,响应消息
                        OutputStream outputStream = socket.getOutputStream();
                        outputStream.write("hello,client...".getBytes());

                    }catch (Exception e){
                        e.printStackTrace();
                    }finally {
                        try {
                            //关闭连接
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }


                }
            });

        }



    }
}

客户端代码:

public class Client {

    public static void main(String[] args) throws IOException, InterruptedException {

        //1. 创建socket对象,绑定服务器的ip和端口
        Socket socket = new Socket("127.0.0.1", 9988);

        //2. 从连接中获取输出流,发送消息
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello,server...I'm client01".getBytes());

        //3. 从连接中取出输入流,接收消息
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int len = inputStream.read(bytes);
        System.out.println("服务器发送消息:" + new String(bytes, 0, len));

        //4. 关闭连接
        socket.close();


    }
}

测试结果:

请添加图片描述

#二、 I/O模型

1、I/O模型分类

  • java支持三种模型:BIO(同步并阻塞)、NIO(同步非阻塞)、AIO(异步非阻塞)

  • 阻塞和非阻塞

    • 当前线程访问io资源时,若资源未准备就绪:
      1. 阻塞:当前线程会一直等待资源就绪。
      2. 非阻塞:当前线程不会等待,可以去访问别的资源。
  • 同步和异步

    • 当前线程访问io资源时,若资源未准备就绪:
      1. 同步:当前线程会等待资源就绪,获取结果。
      2. 异步:当前线程会继续执行其他逻辑,等待资源就绪后的回调。

2、BIO

  • 定义:
    • 传统的socket编程就是bio
  • 使用方式
    • 一个线程对应一个连接处理
  • 缺点:
    • 每个请求都需要创建独立线程,处理客户端的读写等业务处理
    • 并发连接数比较大时,会创建很多线程,系统资源消耗大
    • 连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费

3、NIO

  • 同步非阻塞,一个线程 可以处理多个socket连接请求,客户端发送的请求都会注册到多路复用器(Selector)上,多路复用器轮询到连接有I/O请求就进行处理

4、AIO

  • 异步非阻塞,AIO 引入异步通道的概念,采用了 Proactor 模式,简化了程序编写,有效的请求才启动线程,它的 特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长 的应用

总结

  1. BIO(同步并阻塞) 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高。JDK1.4以前的唯一选择,但程序简单易理解
  2. NIO(同步非阻塞) 方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,弹幕 系统,服务器间通讯等。编程比较复杂,JDK1.4 开始支持
  3. AIO(异步非阻塞) 方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分 调用 OS 参与并发操作, 编程比较复杂,JDK7 开始支持。

,但程序简单易理解
2. NIO(同步非阻塞) 方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,弹幕 系统,服务器间通讯等。编程比较复杂,JDK1.4 开始支持
3. AIO(异步非阻塞) 方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分 调用 OS 参与并发操作, 编程比较复杂,JDK7 开始支持。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值