上一篇我们讲了利用多线程优化系统间通信,本篇我们从通信模型开始讲系统间通信的优化。
优化之前,我们先介绍最初的阻塞式通信模型,即BIO(blocking IO)。
1.阻塞式通信模型是什么呢?阻塞主要是指IO阻塞。前文讲过,系统间通信在两个地方要用到IO操作,一个是应用程序请求操作系统与外部网络建立连接,另一个是应用程序请求操作系统接收外部网络数据传输。而且,我们也讲过,阻塞和非阻塞是指应用程序级别的,而同步和异步是指操作系统级别的。阻塞式通信模型就是指java中socket套接字的实现,换句话说,java中java.net包中的socket套接字提供了阻塞式通信模型的支持。
2.本篇文章主要介绍阻塞式通信模型。
3.服务器端代码:
package BIO;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
OutputStream os = null;
try {
//服务器端接收客户端请求并回写信息
serverSocket = new ServerSocket(9999);
socket = serverSocket.accept();
is = socket.getInputStream();
os = socket.getOutputStream();
byte[] receiveByte = new byte[1024];
StringBuffer receiveMsg = new StringBuffer();
//接收客户端发送的数据
while(is.read()!=-1){
is.read(receiveByte);
receiveMsg.append(new String(receiveByte));
//收到“over”表示客户端已经发送完完整的信息,服务器可以处理请求并在完成之后写回客户端
if(receiveMsg.indexOf("over")!=-1){
break;
}
}
System.out.println(receiveMsg);
//服务器向客户端写回处理结果
byte[] sendByte = new byte[1024];
String sendMsg = "服务端已经收到请求";
sendByte = sendMsg.getBytes();
os.write(sendByte);
os.flush();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
os.close();
is.close();
socket.close();
serverSocket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
4.客户端代码:
package BIO;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
Socket socket = null;
InputStream is = null;
OutputStream os = null;
try {
//客户端请求建立连接
socket = new Socket("localhost", 9999);
is = socket.getInputStream();
os = socket.getOutputStream();
byte[] buffer = new byte[1024];
String msg = "来自客户端的请求over";
buffer = msg.getBytes();
os.write(buffer);
os.flush();
byte[] receiveMsg = new byte[1024];
StringBuffer str = new StringBuffer();
while(is.read()!=-1){
is.read(receiveMsg);
str.append(new String(receiveMsg));
if(str.indexOf("over")!=-1){
break;
}
}
System.out.println("服务器端返回的信息为:"+str);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
is.close();
os.close();
socket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
5.系统间通信用到IO的地方会发生阻塞,所以在上述代码中会发生阻塞的地方就是ServerSocket对象的
accept方法和Socket对象的InputStream对象的
read方法。