补充:RPC与NIO

参考:https://www.cnblogs.com/zjfstudio/p/4090712.html
https://weixiaolu.iteye.com/blog/1479656

1. 阻塞I/O通信模型

假如现在你对阻塞I/O已有了一定了解,我们知道阻塞I/O在调用InputStream.read()方法时是阻塞的,它会一直等到数据到来时(或超时)才会返回;同样,在调用ServerSocket.accept()方法时,也会一直阻塞到有客户端连接才会返回,每个客户端连接过来后,服务端都会启动一个线程去处理该客户端的请求。阻塞I/O的通信模型示意图如下:

如果你细细分析,一定会发现阻塞I/O存在一些缺点。根据阻塞I/O通信模型,我总结了它的两点缺点:

  1. 当客户端多时,会创建大量的处理线程。且每个线程都要占用栈空间和一些CPU时间
  2. 阻塞可能带来频繁的上下文切换,且大部分上下文切换可能是无意义的。

阻塞IO实现的通信代码如下:

ServerSocket server = new ServerSocket(8111);
Socket socket = server.accept();
 
//由Socket对象得到输入流,并构造相应的BufferedReader对象
BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输出流,并构造PrintWriter对象
PrintWriter os = new PrintWriter(socket.getOutputStream());
 
while(true){
   String inline = is.readLine();
   System.out.println(" 收到信息:" + inline);
   //服务器反回
   os.println("serverSend:" + inline);
   os.flush();
   if (inline == "bye")
break;
}
os.close();
is.close();
socket.close();
server.close();
System.out.println("服务器退出");
Socket socket = new Socket("127.0.0.1",8111);
 
//由Socket对象得到输入流,并构造相应的BufferedReader对象
BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输出流,并构造PrintWriter对象
PrintWriter os = new PrintWriter(socket.getOutputStream());
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
while(true){
   System.out.println("请输入:");
   String line = sin.readLine();
   os.println(line);
   os.flush();
   String inline = is.readLine();
   System.out.println("服务器获取值:" + inline);
   if (line=="bye")
      break;
}
os.close();
is.close();
socket.close();
System.out.println("客户端退出");

网络编程中,首先我们要学的就是Socket编程,这是网络编程中最底层的程序接口,分为服务器端和客户端,服务器负责监听某个端口,客户端负责连接服务器上的某个端口,一旦连接通过后,服务器和客户端就可以双向通讯了。
这两段代码分别帖入两个类中,分开执行,先执行服务器端,再执行客户端,就可以互发消息了。

观察下代码,发现代码中下面4~20行逻辑是一至的,都是通过流来通讯,所以Socket中不同的是开始地方,服务器是通过server.accept()来获取Socket,而客户端是通过直接创建Socket对象的。

这段代码,其本运行是没问题的,但存在一个问题,就是当客户端接入时服务器端的accept函数才走下去,不然的话,会一直处于卡死等待状态。包括getInputStream函数,也会等待双方接通后,才往下走。除非等到客户端接入,或中断。当然有人会说,可以引入多线程啊,没错,是可以,但是想一下,是不是每个客户接入都得有一个线程? 否则少一个线程,就会有一堆的卡着。所以这种方式不适合在大最客户端接入的情况。

在这种情况下非阻塞式I/O就有了它的应用前景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值