BIO(blocking IO)同步堵塞IO 是最基础的系统间通信方式。
从程序角度看,BIO就是当发起IO读写的时候,都是堵塞方式,只有当程序读到流或将流写入操作系统后,才释放。从实现角度看,代码比较简单,通过JAVA的Socket和ServerSocket实现TCP/IP通信,并且将一个socket放入到一个线程中处理,通过多线程保证服务端可以接受多个客户端的连接请求。
/**
* 抽象类BaseNetwork,封装了一些常用参数
*
* @author cyx
*
*/
public abstract class BaseNetwork implements Runnable {
Socket socket;
BufferedReader reader;
PrintWriter writer;
Scanner input = new Scanner(System.in);
//关闭连接
public void close() {
try {
input.close();
socket.close();
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("end");
}
// 初始化reader,writer
public void initRW() throws IOException {
reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
writer = new PrintWriter(new OutputStreamWriter(
socket.getOutputStream()), true);
}
}
/**
* 客户端
* @author cyx
*
*/
public class TCPBIOClientThread extends BaseNetwork {
String host = "localhost";
int port = 1234;
public static void main(String[] args) {
new Thread(new TCPBIOClientThread()).start();
}
@Override
public void run() {
try {
socket = new Socket(host, port);
initRW();
while (true) {
String message = input.next();
writer.println(message);
//控制台输入byebye退出连接
if (message.equals("byebye"))
break;
System.out.println(reader.readLine());
}
close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 服务端
*
* @author cyx
*
*/
public class TCPBIOServer {
ServerSocket serverSocket;
public TCPBIOServer() {
try {
serverSocket = new ServerSocket(1234);
} catch (IOException e) {
e.printStackTrace();
}
}
// 循环一直接受客户端的连接,把socket放入到专门的线程中处理
public void service() {
while (true) {
try {
Socket socket = serverSocket.accept();
new Thread(new SocketThread(socket)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
TCPBIOServer server = new TCPBIOServer();
server.service();
}
// 通过多线程实现多个客户端的连接
class SocketThread extends BaseNetwork {
public SocketThread(Socket socket) {
super();
super.socket = socket;
}
@Override
public void run() {
try {
int port = socket.getPort();
System.out.println("收到连接:" + socket.getLocalAddress() + ":"
+ port);
initRW();
while (true) {
String message = reader.readLine();
if (message.equals("byebye")) {
System.out.println(port + "断开连接");
break;
}
writer.println("ok!");
System.out.println(port + ":" + message);
}
close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
结果:
TCP/IP+BIO的demo实现还是比较简单的,但是有很多问题,当客户端太多的时候,服务器受不了,并且频繁创建socket的性能损耗,这个方面可以通过连接池解决。这里使用多线程处理多个客户端的请求会造成服务器资源耗尽,所以BIO方式不太好,下面会学习基于reactor模式的NIO。