Java BIO

Java BIO图解

在这里插入图片描述

同步阻塞案例

package com.design;

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

public class Server {
    public static void main(String[] args) {
        System.out.println("服务器已启动");
        try {
            ServerSocket ss = new ServerSocket(9999);
            Socket socket = ss.accept();
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String msg;
            while ((msg = br.readLine())!=null)
            {
                System.out.println("服务端接收到:"+msg);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我们先在服务器端初始化一个端口为9999的Socket 然后我们初始化字符输入流来获取客户端的信息

package com.design;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1", 9999);
            OutputStream outputStream = socket.getOutputStream();
            PrintStream printStream = new PrintStream(outputStream);
            printStream.print("你好啊,我是阿三");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我们在客户端同样创建一个套接字,并向服务端打印一句话你好啊,我是阿三。
我们先启动服务端
在这里插入图片描述
我们再启动客户端却曝出了错误
在这里插入图片描述
出错的原因是因为我们在客户端调用的是print方法,我们输出了一串字符但却没有输出换行符,而服务端所要读的是一行字符。可还没有等客户端发来一行字符,客户端就已经宕机。如果我们调用pringln方法呢??

在这里插入图片描述
可以看到。这次我们收到了服务端的消息,但由于客户端的宕机,服务端也跟着抛出异常,这其实也是同步阻塞的特点。是一种“浪漫的殉情”的方式,一方宕机,另一方也会跟着抛出异常

BIO实现接受多个客户端

BIO会为每一个客户端创建一个线程

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

public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(9999);
            while (true)
            {
                Socket accept = ss.accept();
                new ThreadServer(accept).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

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

public class ThreadServer extends Thread{
    private Socket socket;

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

    @Override
    public void run() {
        try {
            System.out.println("服务线程"+Thread.currentThread().getName()+"启动了");
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String msg;
            while ((msg = br.readLine())!=null)
            {
                System.out.println("服务端收到消息:"+msg);

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

package com.design;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1", 9999);
            OutputStream outputStream = socket.getOutputStream();
            PrintStream ps = new PrintStream(outputStream);
            Scanner sc = new Scanner(System.in);
            String msg;
            while ((msg = sc.nextLine())!=null)
            {

                ps.println(msg);
                ps.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

以上代码便实现了,每次运行一个Client进程时,服务端都会新建一个线程来进行处理,从而实现了BIO多客户端的应用。在这架构下,本身可以解决多个客户端通讯,但也存在问题。

  • 每次接受客户端请求,都会创建独立线程,切换上下文影响性能
  • 每个线程都会占用栈空间和CPU资源
  • 并不是每个socket都进行IO操作,无意义的线程处理。
  • 客户端的并发访问量增加时,服务端将呈现线程开销大,访问量增大时将发生栈溢出,线程创建失败,最终导致进程宕机。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值