BIO通信模型
BIO通信服务端,通常有一个独立的Acceptor线程负责监听客户端的连接。接收到客户端连接请求后会为每个客户创建一个新的线程进行链路处理,处理完成后返回应答给客户端,也就是经典的请求-应答 通信模型。 但是随着客户端并发数量上升,服务端的线程膨胀,系统性能急剧下降,最终会导致系统不可用。
缺点:
无法满足高并发,高性能的场景。因为它每一个连接就会创建一个新的线程,而创建线程是需要消耗资源的,比如消耗进程的用户空间用来创建栈,PC计数器等。
BIO模型编程步骤:
分为客户端和服务端。 服务端首先创建ServerSocket,等待用户连接。 一个用户连接需要线程来做处理。 以BIO单线程的编程步骤举例。
服务端:
创建ServerSocket实例。绑定占用端口(bind)。通过accept() 方法监听并等待客户端的连接。如果有客户端连接则获得socket实例。通过socket实例进行读写操作。关闭资源和socket。
客户端:
创建socket实例。通过connect()连接服务端。通过socket实例进行读写操作。关闭资源和socket。
BIO编程中有哪些方法是阻塞的?
acceptconnectreadwrite
BIO多线程编码实例:
服务端:
package Internet
.BIODemo
;
import java
.io
.BufferedReader
;
import java
.io
.IOException
;
import java
.io
.InputStreamReader
;
import java
.io
.OutputStream
;
import java
.net
.InetSocketAddress
;
import java
.net
.ServerSocket
;
import java
.net
.Socket
;
class server extends Thread{
private Socket socket
;
public server(Socket socket
){
this.socket
=socket
;
}
@Override
public void run() {
try {
System
.out
.println("有新用户连接"+socket
.getRemoteSocketAddress());
BufferedReader reader
=new BufferedReader(new InputStreamReader(socket
.getInputStream()));
OutputStream outputStream
=socket
.getOutputStream();
String msg
=null
;
while((msg
=reader
.readLine())!=null
){
System
.out
.println(Thread
.currentThread().getName()+"->"+socket
.getRemoteSocketAddress()+" "+msg
);
outputStream
.write(msg
.getBytes());
outputStream
.flush();
msg
=null
;
}
outputStream
.close();
reader
.close();
} catch (IOException e
) {
e
.printStackTrace();
}
}
}
public class BIOServer {
public static void main(String
[] args
) {
try {
ServerSocket serverSocket
=new ServerSocket();
serverSocket
.bind(new InetSocketAddress(8888));
System
.out
.println("服务端启动"+Thread
.currentThread().getName());
Socket socket
=null
;
while((socket
=serverSocket
.accept())!=null
){
server s
=new server(socket
);
s
.start();
}
serverSocket
.close();
} catch (IOException e
) {
e
.printStackTrace();
}
}
}
客户端:
package Internet
.BIODemo
;
import javax
.swing
.*
;
import java
.io
.*
;
import java
.net
.InetSocketAddress
;
import java
.net
.Socket
;
import java
.util
.Scanner
;
public class BIOClient {
public static void main(String
[] args
) throws IOException
{
Socket socket
=new Socket();
socket
.connect(new InetSocketAddress("127.0.0.1",8888));
OutputStream outputStream
=socket
.getOutputStream();
InputStream read
=socket
.getInputStream();
Scanner scanner
=new Scanner(System
.in
);
scanner
.useDelimiter("\n");
while(scanner
.hasNext()){
String nextLine
=scanner
.nextLine();
outputStream
.write((nextLine
+"\n").getBytes());
outputStream
.flush();
byte [] bytes
=new byte[1024];
int num
=read
.read(bytes
);
System
.out
.println("Reci "+new String(bytes
,0,num
));
}
read
.close();
outputStream
.close();
socket
.close();
}
}