java_bio编程

简介

        Bio 有的人称为BasicIO,有的称block(阻塞)IO,主要应用于文件IO和网络IO,在JDK1.4之前,我们建立网络连接的时候只能采用BIO,需要先在服务器端启动一个serverSocket,然后在客户端启动socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后先咨询服务端是否有线程影响,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端线程就会等待请求结束后才继续执行,这就是阻塞式

下面利用客户端和服务端的代码进行解释:

服务器端

  总体思路

    //创建SocketServer对象

    //判断联机是否成功

    //循环监听消息

    //获取客户端写入的流

    //向客户端写数据

  主体代码

public class TCPServer {
    public static void main(String[] args) throws IOException {
        //创建SocketServer对象
        ServerSocket socketServer = new ServerSocket(3000);
        //判断联机是否成功
        boolean connected = socketServer.isBound();
        if(connected){
            System.out.println("绑定成功!!!");
        }else{
            System.out.println("未知错误!!!");
        }
        //循环监听消息
        while (true) {
            //如果检测不到请求,就会阻塞到这,停止到这里
            Socket s1 = socketServer.accept();//阻塞方法
            InputStream inputStream = s1.getInputStream();//获取客户端写入的流
            byte[] b = new byte[100];
            inputStream.read(b);
            String hostAddress = s1.getInetAddress().getHostAddress();//获取客户的ip地址
//            System.out.println("客户ip为"+hostAddress+":"+new String(b).trim());//显示客户内容
            System.out.println(new String(b).trim());//显示客户内容
            System.out.println("客服:");
            Scanner scanner = new Scanner(System.in);
            String str = scanner.nextLine();
            String smsg ="客服:"+str;
            OutputStream outputStream = s1.getOutputStream();
            outputStream.write(smsg.getBytes());
        }
    }
}  

 在这里,传统io阻塞的最明显的情况就是Socket s1 = socketServer.accept();,当没有客户端连接,程序就停在这里即阻塞这里,知道检测到客户端连接才继续向下执行

客户端

  总体思路 

    //循环发出消息

    //判断联机是否成功

    //获取客户端写入的流

    //向客户端写数据

  主体代码

public class TCPClient {
    public static void main(String[] args) throws IOException {
        //循环发出消息
        while (true) {
            //创建socket对象
            Socket s = new Socket("127.0.0.1", 3000);
            //判断联机是否成功
            boolean connected = s.isConnected();
            if(connected){
                System.out.println("连接成功!!!");
            }else{
                System.out.println("未知错误!!!");
            }
            //从链接中取出输出流并发消息
            OutputStream outputStream = s.getOutputStream();
            System.out.println("客户:");
            Scanner scanner = new Scanner(System.in);
            String s1 = scanner.nextLine();
            String cmsg="客户:"+s1;
            //把输入的数据写如网络流
            outputStream.write(cmsg.getBytes());
            //从链接流取出输入流并接受回话
            InputStream inputStream = s.getInputStream();
            byte[] b = new byte[100];
            inputStream.read(b);
            System.out.println(new String(b).trim());
            //关闭流
        }
    }  

多线程版

与单机版不同的是,就是改造了一下服务器端,首先要做到循环获取客户端的数据,这样的话就需要使用--while(ture){}代码块,然后将接受客户端消息和向客户端发送消息,放入线程中,并且循环获取客户端发送的数据,并循环向客户端发送数据,此时同样需要在run方法中,放置while(true){}代码块

  服务器端

public class IoService {
    public static void main(String[] args) throws IOException {
        // 創建多個線程,模擬多個客戶端連接服務端
        ServerSocket serverSocket = new ServerSocket(3333);
        //循环开启线程
        while (true) {
            // accept这个方法是阻塞的,所以只能等到一个连接结束,才能进行下一个连接进来
            Socket s1 = serverSocket.accept();//阻塞方法
            new Thread() {
                public void run() {
                    try {
                        //接受客户端消息
                        InputStream inputStream = s1.getInputStream();//获取客户端写入的流
                        //给客户端发送消息
                        OutputStream outputStream = s1.getOutputStream();

                        while (true) {
                            //获取客户端发送的数据
                            byte[] b = new byte[100];
                            inputStream.read(b);
                            System.out.println(new String(b).trim());
                            //向客户端发送数据
                            //输入数据
                            System.out.println("请输入:");
                            Scanner scanner = new Scanner(System.in);
                            String s1 = scanner.nextLine();
                            String cmsg = "客服:" + s1;
                            //把输入的数据写如网络流
                            outputStream.write(cmsg.getBytes());
                        }
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.getMessage();
                    }
                }
            }.start();
        }
    }

 

  客户端

public class IoClient {
    public static void main(String[] args) {
        // 創建多個線程,模擬多個客戶端連接服務端
        try {
            Socket s = new Socket("127.0.0.1", 3333);
            OutputStream outputStream = s.getOutputStream();
            InputStream inputStream = s.getInputStream();

            while (true) {
                try {
                    Scanner scanner = new Scanner(System.in);
                    System.out.println("请输入:");
                    //从链接中取出输出流并发消息
                    String s1 = scanner.nextLine();
                    String cmsg = "客户1:" + s1;
                    //把输入的数据写如网络流
                    outputStream.write(cmsg.getBytes());
                    //从链接流取出输入流并接受回话
                    // 設置下標
                    byte[] b = new byte[100];
                    inputStream.read(b);
                    System.out.println(new String(b).trim());
                } catch (Exception e) {
                    e.getMessage();
                }
            }
        } catch (Exception e) {
            e.getMessage();
        }
    }
}

  在这块提示:idea可以将同一个main方法执行多次

 

posted @ 2019-04-28 21:52  Kill(Bug)  阅读(81)  评论(0)    收藏  举报