大话netty系列之--BIO
学渣与学霸
大明与老王是大学同学,大明是典型的三好学生,学习优秀,生活自律,并且是学生会一员,在班级人缘也好;
而老王每天游离在课堂与社会之间,与同学们见面的次数很少,平常不是网吧就是和他们的一帮朋友出去花天酒地!
==============================分割线========================================
话说,转眼间已经毕业四年了,同学们举行了一次大学同学聚会,再一次回到了母校,晚上吃饭吃的很high,每个人变化都特别大,大明毕业后进了一家国企,但是厌倦了那种每天平淡的生活,出来自己创业;而老王则是待在了一家小私企,郁郁不得志,安心的做了一个业务员。
大明:老王,你变化好大啊
老王:是啊,没想到你竟然在大国企辞职了,现在做什么生意啊
大明:哪算的上生意啊,就是平时买点东北特产,到南方再去销售,混口饭吃呗。。
老王:那巧了,我在东北这好多熟人,我可以找到便宜又好的货源啊,我帮你联系。
大明:那咱俩合作搞一个一条龙吧,你负责在东北买货源,发给我,我负责收货后在南方销售;敲定之后,他俩雇了个人专门负责在中间送货
=================================分割线==========================================
我们用程序来演示下两个人的合作之路。我们把老王当做客户端,负责收集东北特产,大明当做服务端,负责接收特产,小美作为中间人,负责物流运送。
1.服务端--大明,负责接收老王的特产
/**
* 大明,负责接收老王发过来的特产
*
* @author wangmj
* @since 2018/11/18
*/
public class BioServer {
public static void main(String[] args) {
int port = 8761;
ServerSocket serverSocket = null;
try {
//创建大明类,负责接收老王的特产
serverSocket = new ServerSocket(port);
System.out.println("大明类成功创建");
Socket socket = null;
while (true) {
socket = serverSocket.accept();
//将具体任务派发给小美
new Thread(new BioServerHandler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.小美--负责帮大明接收货物并发送物流
/**
* 小美 负责中间物流配送处理
*
* @author wangmj
* @since 2018/11/18
*/
public class BioServerHandler implements Runnable {
private Socket socket;
public BioServerHandler(Socket socket) {
this.socket = socket;
}
public void run() {
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
//从大明收到的特产
String messageFromDM = null;
while (true) {
messageFromDM = in.readLine();
if (messageFromDM == null) {
break;
}
System.out.println("收到老王的特产=" + messageFromDM);
out.println("老铁,已收到特产,接收时间:" + new Date());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (out != null) {
out.close();
}
}
}
}
3.老王--负责发送东北特产
/**
* 老王,负责购买特产,发送给大明
*
* @author wangmj
* @since 2018/11/18
*/
public class BioClient {
public static void main(String[] args) {
int port = 8761;
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
//创建客户端soket--老王
socket = new Socket("127.0.0.1", port);
//获取输出流,向服务器发送消息
OutputStream os = socket.getOutputStream();
out = new PrintWriter(os, true);
out.println("今天给你发送东北特产100斤,发送时间:" + new Date());
System.out.println("老王的东北特产成功送出");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//收到服务端的响应
String resp = in.readLine();
System.out.println("收到大明的反馈=" + resp);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
try {
if (in != null) {
in.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
三个人物都已创建完毕,下面我们一次启动大明与老王类,看下运行结果:
老王:
大明:
原理分析:
我们知道BIO是阻塞IO,读与写都会发生阻塞,一旦创建连接,就不能接收其他的连接请求,直到释放连接后才去处理下一个连接请求,这样会导致效率大大降低;我们分析下刚才创建的模型图
我们分析下这样有什么坏处呢?
1.一应一答阻塞读写会很影响效率
2.每一个连接都会创建一个线程去阻塞连接,当连接数量很大时会创建大量线程,但是由于阻塞特性,效率不一定提高
那么我们如何改进这个模式呢,当老王和大明的业务量越来越多,就会造成两个人忙得不可开交,并且为了解决这个问题,就会为每次配送都雇佣一个人,导致成本急剧增加,最终资源耗尽,生意失败。下一小节我们将试着改进下这种BIO模式