在使用传统的ServerSocket和Socket的时候很多时候程序是会阻塞的。比如serversocket.accept() , socket.getInputStream().read() 的时候都会阻塞。
在ServerSocket与Socket的方式中,服务器端往往要为每一个客户端连接(socket)分配一个线程,而每一个线程都有可能处于长时间的阻塞状态中。而过多的线程也会影响服务器的性能。在JDK1.4引入了非阻塞的通信方式(NIO,这样使得服务器端只需要一个线程就能处理所有客户端socket的请求)
【实例1:单机版】
1)Server
public class Server{
publicstatic void main(String[] args) throws IOException {
//创建一个ServerSocket在端口4700监听客户请求
ServerSocketserver = new ServerSocket(5678);
/**
* 使用accept()阻塞等待客户连接,有客户请求到来则产生一个Socket对象,并继续执行
*/
Socketsocket = server.accept();
//由Socket对象得到输入流,并构造相应的BufferedReader对象
BufferedReaderin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输出流,并构造PrintWriter对象
PrintWriter out =new PrintWriter(socket.getOutputStream());
while (true) {
//阻塞读取客户端发送的数据、并向标准输出
String str = in.readLine();
System.out.println(str);
//向客户端输出字符,并刷新输出流,使Client马上收到该字符串
out.println("hasreceive....");
out.flush();
if(str.equals("end"))
break;
}
out.close();//关闭socket输出流
in.close();//关闭socket输入流
socket.close();//关闭socket
server.close();//关闭serverSocket
}
}
2)Client
public class Client{
staticSocket server;
publicstatic void main(String[] args) throws Exception{
//向本机的5678端口发出客户请求
server= new Socket(InetAddress.getLocalHost(), 5678);
//由Socket对象得到输入流,并构造相应的BufferedReader对象
BufferedReader in = newBufferedReader(new InputStreamReader(server.getInputStream()));
//由Socket对象得到输出流,并构造PrintWriter对象
PrintWriter out = newPrintWriter(server.getOutputStream());
//由系统标准输入设备构造BufferedReader对象
BufferedReader wt = newBufferedReader(new InputStreamReader(System.in));
while (true) {
//从标准输入读取
String str = wt.readLine();
//向服务器端输出字符,并刷新输出流,使server马上收到该字符串
out.println(str);
out.flush();
if (str.equals("end")){
break;
}
System.out.println(in.readLine());
}
out.close();//关闭Socket输出流
in.close();//关闭Socket输入流
server.close();//关闭Socket
}
}
说明:上面代码,只能有一个客户端链接到服务器。一旦有一个客户端链接到了服务器,服务器代码就会一直处在while死循环中,和客户端通信,直到客户端退出。
【实例2:多线程版】
1)ServerThread
public classServerThread extends Thread{
privateSocket socket;
public ServerThread(Socket s) {
this.socket = s;
}
public void run() {
try {
//构造socket的输入流
BufferedReader in = newBufferedReader(new InputStreamReader(socket.getInputStream()));
//根据socket构造输出流
PrintWriter out = newPrintWriter(socket.getOutputStream());
// Mutil User but can'tparallel
while (true) {
//读取客户端输入流中内容
String str =in.readLine();
System.out.println(str);
//向客户端输出
out.println("hasreceive....");
out.flush();
if(str.equals("end"))
break;
}
out.close();
in.close();
socket.close();
} catch (IOException ex) {
} finally {
}
}
publicstatic void main(String[] args) throws IOException {
ServerSocketserver = new ServerSocket(5678);
while(true) {
//每一个客户端连接(server.accept())分配一个线程来处理
ServerThread mc = new ServerThread(server.accept());
mc.start();
}
}
}
2)客户端代码同上;
3)说明: