网络通信——BIO

        网络通信在编程世界中是必不可少的一部分,到目前为止网络通信主要经历了三个阶段BIO,NIO,AIO。本文主要介绍网络通信涉及到的一些概念,并且采用一个网络通信的Demo展示何为BIO——阻塞IO。

基础概念

1、阻塞、非阻塞

         阻塞和非阻塞是指进程在访问数据的时候,数据内部是否准备就绪的一种处理方式。当数据没有准备的时候
阻塞:需要等待缓冲区的数据准备好才去处理之后的事情,否则一直等待下去
非阻塞:无论缓冲区的数据是否准备好,都立刻返回

2、同步、异步

         同步和异步都是基于应用程序和操作系统处理IO时间锁采用的方式。
同步:应用程序要直接参与IO读写的操作,在处理IO事件的时候必须阻塞在某个方法上的等待我们IO完成的时间(阻塞IO事件或者通过轮询IO事件的方式)。阻塞直到IO事件遇到write或者read,这个时候我们不能做任何我们想去做的事情,让读写方法加入到线程中,通过阻塞线程来实现,这样对线程的性能消耗比较大。
异步:所有的IO读写都交给操作系统处理,此时应用程序可以处理其他事情,当操作系统完成IO后给应用程序一个通知即可。

3、Java IO实现方式

1)、同步,阻塞IO——BIO-(JDK1.4以前)

2)、IO事件轮询,多路复用技术(select)——NIO-(JDK1.4—1.6)

3)、异步非阻塞IO——AIO-(JDK1.7以及以后)

接下小编主要介绍BIO的一个Demo,实现类似于聊天室的功能,用于理解何为阻塞IO

SocketService 服务端

package com.mandy.nio.service;

import com.mandy.nio.headler.ServerHandler;

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

/**
 * @author 贾文静
 * @version 1.0
 * @title
 * @description 服务端socket 当没有客户连接时会一直堵塞
 */
public class SocketService {
    final static int PORT = 7789;

    public static void main(String[] args) {
        try {
            ServerSocket server = new ServerSocket(PORT);
            System.out.println("server start...");
            //堵塞
            Socket socket = server.accept();
            //创建线程用于真正的读写处理
            new Thread(new ServerHandler(socket)).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务端真正的线程处理逻辑 

package com.mandy.nio.headler;

import java.io.*;
import java.net.Socket;

/**
 * @author 贾文静
 * @version 1.0
 * @title
 * @description 真正用于处理读写操作的线程
 */
public class ServerHandler implements Runnable {

    private Socket socket;


    public ServerHandler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
             PrintWriter out = new PrintWriter(this.socket.getOutputStream(), true)) {
            String body = null;
            while (true) {
                //用于接收客户的请求数据
                body = in.readLine();
                if (body == null) {
                    break;
                }
                System.out.println("客户端say:");
                System.out.println(body);
                System.out.println("服务端say:");
                //为客户端响应数据
                String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
                out.println(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户端请求连接 

package com.mandy.nio.client;

import org.springframework.util.StringUtils;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * @author 贾文静
 * @version 1.0
 * @title
 * @description 客户端socket 通过ip+端口去连接serviceSocket ,当没有找服务端直接抛出java.net.ConnectException: Connection refused (Connection refused)
 */
public class SocketClient {

    final static String ADDRESS = "127.0.0.1";
    final static int PORT = 7789;

    public static void main(String[] args) {

        try (Socket socket = new Socket(ADDRESS, PORT)) {
            //从服务器读取数据
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //向服务端发送数据
            PrintStream output = new PrintStream(socket.getOutputStream());
            System.out.println("客户端说:");
            String str = new BufferedReader(new InputStreamReader(System.in)).readLine();
            output.println(str);
            String response = null;
            while (true) {
                response = reader.readLine();
                if (StringUtils.isEmpty(response)) {
                    break;
                }
                System.out.println("服务器说:");
                System.out.println(response);
                if ("OK".equals(response)) {
                    System.out.print("程序即将关闭");
                    break;
                } else {
                    System.out.println("客户端说:");
                    String client = new BufferedReader(new InputStreamReader(System.in)).readLine();
                    output.println(client);
                }
            }
            output.close();
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

当没有客户端请求,服务端启动后一直处于阻塞状态

当客户端发送请求通信时,客户端阻塞等待服务端的响应

        从功能实现来说利用socket bio的原理实现一个简单聊天室,这个相比我们平常使用的微信,QQ,钉钉等来说只能和一个人聊天,要想和其他人通信只能等这个通信彻底结束,对于实际场景来说不满足实际情况,对于服务器,对线程资源也是极大的损耗, 从技术上来说 JDK1.4之后推出了NIO 多路复用技术来解决线程资源损耗的问题,关于聊天室这个功能也会伴随着NIO而逐步增强的,具体内容,下篇博客更新。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mandy_i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值