java_bio编程
简介
Bio 有的人称为BasicIO,有的称block(阻塞)IO,主要应用于文件IO和网络IO,在JDK1.4之前,我们建立网络连接的时候只能采用BIO,需要先在服务器端启动一个serverSocket,然后在客户端启动socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后先咨询服务端是否有线程影响,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端线程就会等待请求结束后才继续执行,这就是阻塞式
下面利用客户端和服务端的代码进行解释:
服务器端
总体思路
//创建SocketServer对象
//判断联机是否成功
//循环监听消息
//获取客户端写入的流
//向客户端写数据
主体代码
public class TCPServer {
public static void main(String[] args) throws IOException {
//创建SocketServer对象
ServerSocket socketServer = new ServerSocket(3000);
//判断联机是否成功
boolean connected = socketServer.isBound();
if(connected){
System.out.println("绑定成功!!!");
}else{
System.out.println("未知错误!!!");
}
//循环监听消息
while (true) {
//如果检测不到请求,就会阻塞到这,停止到这里
Socket s1 = socketServer.accept();//阻塞方法
InputStream inputStream = s1.getInputStream();//获取客户端写入的流
byte[] b = new byte[100];
inputStream.read(b);
String hostAddress = s1.getInetAddress().getHostAddress();//获取客户的ip地址
// System.out.println("客户ip为"+hostAddress+":"+new String(b).trim());//显示客户内容
System.out.println(new String(b).trim());//显示客户内容
System.out.println("客服:");
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
String smsg ="客服:"+str;
OutputStream outputStream = s1.getOutputStream();
outputStream.write(smsg.getBytes());
}
}
}
在这里,传统io阻塞的最明显的情况就是Socket s1 = socketServer.accept();,当没有客户端连接,程序就停在这里即阻塞这里,知道检测到客户端连接才继续向下执行
客户端
总体思路
//循环发出消息
//判断联机是否成功
//获取客户端写入的流
//向客户端写数据
主体代码
public class TCPClient {
public static void main(String[] args) throws IOException {
//循环发出消息
while (true) {
//创建socket对象
Socket s = new Socket("127.0.0.1", 3000);
//判断联机是否成功
boolean connected = s.isConnected();
if(connected){
System.out.println("连接成功!!!");
}else{
System.out.println("未知错误!!!");
}
//从链接中取出输出流并发消息
OutputStream outputStream = s.getOutputStream();
System.out.println("客户:");
Scanner scanner = new Scanner(System.in);
String s1 = scanner.nextLine();
String cmsg="客户:"+s1;
//把输入的数据写如网络流
outputStream.write(cmsg.getBytes());
//从链接流取出输入流并接受回话
InputStream inputStream = s.getInputStream();
byte[] b = new byte[100];
inputStream.read(b);
System.out.println(new String(b).trim());
//关闭流
}
}
多线程版
与单机版不同的是,就是改造了一下服务器端,首先要做到循环获取客户端的数据,这样的话就需要使用--while(ture){}代码块,然后将接受客户端消息和向客户端发送消息,放入线程中,并且循环获取客户端发送的数据,并循环向客户端发送数据,此时同样需要在run方法中,放置while(true){}代码块
服务器端
public class IoService {
public static void main(String[] args) throws IOException {
// 創建多個線程,模擬多個客戶端連接服務端
ServerSocket serverSocket = new ServerSocket(3333);
//循环开启线程
while (true) {
// accept这个方法是阻塞的,所以只能等到一个连接结束,才能进行下一个连接进来
Socket s1 = serverSocket.accept();//阻塞方法
new Thread() {
public void run() {
try {
//接受客户端消息
InputStream inputStream = s1.getInputStream();//获取客户端写入的流
//给客户端发送消息
OutputStream outputStream = s1.getOutputStream();
while (true) {
//获取客户端发送的数据
byte[] b = new byte[100];
inputStream.read(b);
System.out.println(new String(b).trim());
//向客户端发送数据
//输入数据
System.out.println("请输入:");
Scanner scanner = new Scanner(System.in);
String s1 = scanner.nextLine();
String cmsg = "客服:" + s1;
//把输入的数据写如网络流
outputStream.write(cmsg.getBytes());
}
} catch (Exception e) {
// TODO: handle exception
e.getMessage();
}
}
}.start();
}
}
客户端
public class IoClient {
public static void main(String[] args) {
// 創建多個線程,模擬多個客戶端連接服務端
try {
Socket s = new Socket("127.0.0.1", 3333);
OutputStream outputStream = s.getOutputStream();
InputStream inputStream = s.getInputStream();
while (true) {
try {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入:");
//从链接中取出输出流并发消息
String s1 = scanner.nextLine();
String cmsg = "客户1:" + s1;
//把输入的数据写如网络流
outputStream.write(cmsg.getBytes());
//从链接流取出输入流并接受回话
// 設置下標
byte[] b = new byte[100];
inputStream.read(b);
System.out.println(new String(b).trim());
} catch (Exception e) {
e.getMessage();
}
}
} catch (Exception e) {
e.getMessage();
}
}
}
在这块提示:idea可以将同一个main方法执行多次



浙公网安备 33010602011771号