网络I/O编程2 BIO
Posted 健康平安的活着
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络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;
/**
* @ClassName: BioExample
* @Description: TODO
* @Author: liujianfu
* @Date: 2022/05/12 14:25:46
* @Version: V1.0
**/
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);
);
/**
* @author liujianfu
* @description 编写一个handler方法,和客户端进行通讯
* @date 2022/5/12 14:34
* @param [socket]
* @return void
*/
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操作上,造成线程资源浪费。
以上是关于网络I/O编程2 BIO的主要内容,如果未能解决你的问题,请参考以下文章