Java网络编程精解之ServerSocket用法详解三(1)

发表于:2007-06-11来源:作者:点击数: 标签:
第3章 ServerSocket用法详解 第10章 Java 语言的反射机制 第13章 基于MVC和R MI 的分布 ServerSocket用法详解一 Java语言的反射机制一 基于MVC和RMI的分布式应用一 ServerSocket用法详解二 Java语言的反射机制二 基于MVC和RMI的分布式应用二 ServerSocket用

第3章 ServerSocket用法详解 第10章 Java语言的反射机制 第13章 基于MVC和RMI的分布
ServerSocket用法详解一
Java语言的反射机制一
基于MVC和RMI的分布式应用一
ServerSocket用法详解二
Java语言的反射机制二
基于MVC和RMI的分布式应用二
ServerSocket用法详解三
   

相关文章链接:

Java网络编程精解之ServerSocket用法详解一

Java网络编程精解之ServerSocket用法详解二

3.7  关闭服务器

前面介绍的EchoServer服务器都无法关闭自身,只有依靠操作系统来强行终止服务器程序。这种强行终止服务器程序的方式尽管简单方便,但是会导致服务器中正在执行的任务被突然中断。如果服务器处理的任务不是非常重要,允许随时中断,则可以依靠操作系统来强行终止服务器程序;如果服务器处理的任务非常重要,不允许被突然中断,则应该由服务器自身在恰当的时刻关闭自己。

本节介绍的EchoServer服务器就具有关闭自己的功能。它除了在8000端口监听普通客户程序EchoClient的连接外,还会在8001端口监听管理程序AdminClient的连接。当EchoServer服务器在8001端口接收到了AdminClient发送的“shutdown”命令时,EchoServer就会开始关闭服务器,它不会再接收任何新的EchoClient进程的连接请求,对于那些已经接收但是还没有处理的客户连接,则会丢弃与该客户的通信任务,而不会把通信任务加入到线程池的工作队列中。另外,EchoServer会等到线程池把当前工作队列中的所有任务执行完,才结束程序。

如例程3-10所示是EchoServer的源程序,其中关闭服务器的任务是由shutdown- Thread线程来负责的。

例程3-10  EchoServer.java(具有关闭服务器的功能) 

package multithread4;

import java.io.*;

import java.net.*;

import java.util.concurrent.*;

public class EchoServer {

private int port=8000;

private ServerSocket serverSocket;

private ExecutorService executorService;     //线程池

private final int POOL_SIZE=4;       //单个CPU时线程池中工作线程的数目



private int portForShutdown=8001;      //用于监听关闭服务器命令的

端口

private ServerSocket serverSocketForShutdown;

private boolean isShutdown=false;     //服务器是否已经关闭

private Thread shutdownThread=new Thread(){     //负责关闭服务器的线程

public void start(){

this.setDaemon(true);       //设置为守护线程(

也称为后台线程)

super.start();

}

public void run(){

while (!isShutdown) {

Socket socketForShutdown=null;

try {

socketForShutdown= serverSocketForShutdown.aclearcase/" target="_blank" >ccept();

BufferedReader br = new BufferedReader(

new InputStreamReader(socketForShutdown.getInputStream()));

String command=br.readLine();

if(command.equals("shutdown")){

long beginTime=System.currentTimeMillis();

socketForShutdown.getOutputStream().write("服务器正在关闭\r\n".getBytes());

isShutdown=true;

//请求关闭线程池

//线程池不再接收新的任务,但是会继续执行完工作队列中现有的任务

executorService.shutdown(); 



//等待关闭线程池,每次等待的超时时间为30秒

while(!executorService.isTerminated())

executorService.awaitTermination(30,TimeUnit.SECONDS);



serverSocket.close(); //关闭与EchoClient客户通信的ServerSocket

long endTime=System.currentTimeMillis();

socketForShutdown.getOutputStream().write(("服务器已经关闭,"+

"关闭服务器用了"+(endTime-beginTime)+"毫秒\r\n").getBytes());

socketForShutdown.close();

serverSocketForShutdown.close();



}else{

socketForShutdown.getOutputStream().write("错误的命令\r\n".getBytes());

socketForShutdown.close();



}catch (Exception e) {

e.printStackTrace();

}

}

}

};

public EchoServer() throws IOException {

serverSocket = new ServerSocket(port);

serverSocket.setSoTimeout(60000);    //设定等待客户连接的超过时间为60秒

serverSocketForShutdown = new ServerSocket(portForShutdown);

//创建线程池

executorService= Executors.newFixedThreadPool(

Runtime.getRuntime().availableProcessors() * POOL_SIZE);



shutdownThread.start();     //启动负责关闭服务器的线程

System.out.println("服务器启动");

}



public void service() {

while (!isShutdown) {

Socket socket=null;

try {

socket = serverSocket.accept();

//可能会抛出SocketTimeoutException和SocketException

socket.setSoTimeout(60000);     //把等待客户发送数据的超时时间设为60秒

executorService.execute(new Handler(socket));

//可能会抛出RejectedExecutionException

}catch(SocketTimeoutException e){

//不必处理等待客户连接时出现的超时异常

}catch(RejectedExecutionException e){

try{

if(socket!=null)socket.close();

}catch(IOException x){}

return;

}catch(SocketException e) {

//如果是由于在执行serverSocket.accept()方法时,

//ServerSocket被ShutdownThread线程关闭而导致的异常,就退出service()方法

if(e.getMessage().indexOf("socket closed")!=-1)return;

}catch(IOException e) {

e.printStackTrace();

}

}

}

public static void main(String args[])throws IOException {

new EchoServer().service();

}

}

/** 负责与单个客户通信的任务,代码与3.6.1节的例程3-5的Handler类相同 */

class Handler implements Runnable{…}


共3页: 1 [2] [3] 下一页

原文转自:http://www.ltesting.net

评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
...