栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

网络I/O编程2 BIO

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

网络I/O编程2 BIO

一 BIO 1.1 BIO特点

BIO(blocking i/o): 同步阻塞,务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情就会造成不必要的连接开销。可以通过线程池机制改善。

1.2 BIO的工作流程

1.服务器启动一个ServerSocket
2.客户端启动Socket对服务器进行通信,默认情况下服务器端要对每个客户建立一个线程与之通讯。
3.客户端发出请求后,先咨询服务器是否有线程响应,如果没有则会等待,或者被拒绝。
4.如果有响应,客户端线程会等待请求结束后,再继续执行。

二 BIO实操案例 2.1 需求描述

1.使用BIO模型编写一个服务器端,监听6666端口,当有客户端连接时,就启动一个线程与之通讯。
2.要求使用线程池机制改善,可以连接多个客户端
3.服务器可以接收客户端发送的数据,使用telnet方式做验证。

2.2 上代码
package com.ljf.netty.bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class BioExample {
    public static void main(String[] args) throws IOException {
        //1.创建一个线程池
        //2.如果有客户端连接,就创建一个线程,与之通讯。
        ExecutorService executorService = Executors.newCachedThreadPool();
        ServerSocket serverSocket = new ServerSocket(6666);
         System.out.println("服务器启动了!!!");
        while (true) {
            System.out.println("等待客户端的连接.....");
            //阻塞监听客户端
            final Socket socket = serverSocket.accept();
            System.out.println("已经连接上一个客户端.....");
            //创建一个新的线程处理连接
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    handler(socket);
                }
            });
        }

    }
    
    private static void handler(final Socket socket) {
        try {
            System.out.println("线程信息id="+Thread.currentThread().getId()+" 线程name:"+Thread.currentThread().getName());
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            //循环读取
            while (true) {
                System.out.println("线程信息id="+Thread.currentThread().getId()+" 线程name:"+Thread.currentThread().getName());
                int read=inputStream.read(bytes);
                if (read != -1) {
                    String str = new String(bytes,0,read, Charset.defaultCharset());
                    System.out.println(str);
                }
                else{
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("关闭客户端的连接!!!!");
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

启动cmd客户端:

输入   telnet  localhost  6666

然后,按住 ctr+] ,进入发送模式

查看结果:

 2.3 不足之处

每个请求都需要创建独立的线程,当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大。

连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在Read操作上,造成线程资源浪费。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/876678.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号