在I/O编程过程中,当需要同时处理多个客户端接入请求时,可以利用多线程或者I/O多路复用技术进行处理。
I/O多路复用技术通过把多个I/O的阻塞复用到同一个select的阻塞上,从而是的系统在单线程的情况下可以同时处理多个客户端请求。
传统的BIO
网络编程的基本模型时C/S模型,也就是两个线程之间的通信,其中服务端提供位置信息(ip:port),客户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手建立连接,双方就可以通过网络套接字进行通信。
ServerSocket负责绑定ip地址,启动监听端口;
Socket负责发起连接操作。
由一个独立的Acceptor线程负责监听客户端连接,收到客户端连接请求后为每个客户端创建一个新的线程进行链路处理,处理完成之后,通过输出流返回应答给客户端,线程销毁。
并发量增加之后,系统性能会急剧下降-->线程堆栈溢出-->创建新线程失败-->进程宕机。
package buffered.NIO.NIODome1;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class BioTimeServer {
// private static final int port = 8080;
// private ServerSocket serverSocket = null;
public static void main(String[] args) throws IOException {
int port = 8080;
if (args != null && args.length > 0){
try {
port = Integer.valueOf(args[0]);
}catch (NumberFormatException e){
}
}
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
System.out.println(port);
Socket socket = null;
while (true){
socket = serverSocket.accept();
new Thread(new TimeServerHandler(socket)).start();
}
}catch (IOException e){
e.printStackTrace();
}
finally {
if (serverSocket != null){
serverSocket.close();
}
}
}
}
package buffered.NIO.NIODome1;
import javafx.print.Printer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class TimeServerHandler implements Runnable {
private Socket socket;
public TimeServerHandler(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader bufferedReader = null;
PrintWriter printWriter = null;
try {
bufferedReader = new BufferedReader( new InputStreamReader(this.socket.getInputStream()));
printWriter = new PrintWriter(this.socket.getOutputStream(),true);
String currentTime = null;
String body = null;
while (true){
body = bufferedReader.readLine();
if (body == null){
break;
}
System.out.println(body);
currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body)?"11111":"22222222";
System.out.println(currentTime);
}
}catch (IOException e){
if ( bufferedReader != null ){
try {
bufferedReader.close();
}catch ( IOException e1){
e1.printStackTrace();
}
}
if ( printWriter != null){
printWriter.close();
printWriter = null;
}
if ( this.socket != null){
try {
this.socket.close();
}catch ( IOException e2 ){
e2.printStackTrace();
}
this.socket = null;
}
}
}
}
package buffered.NIO.NIODome1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class BioClient {
// private static final int port = 8080;
public static void main(String[] args) {
int port = 8080;
if (args != null && args.length > 0){
try {
port = Integer.valueOf(args[0]);
}catch (NumberFormatException e){
}
}
Socket socket = null;
BufferedReader bufferedReader = null;
PrintWriter printWriter = null;
try{
socket = new Socket("127.0.0.1",port);
bufferedReader = new BufferedReader(new InputStreamReader(
socket.getInputStream()
));
printWriter = new PrintWriter(socket.getOutputStream(),true);
printWriter.println("QUERY TIME ORDER");
String resp = bufferedReader.readLine();
System.out.println(resp);
}catch (Exception e){
}finally {
try {
printWriter.close();
bufferedReader.close();
socket.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}