JAVA 를 이용해서 자체 적 으로 서버 를 닫 을 수 있 는 방법 을 알려 드릴 게 요.

13095 단어 JAVA서버
JAVA 자체 적 으로 닫 을 수 있 는 서버 구현
일반적으로 실 현 된 서버 는 자신 을 닫 을 수 없고 운영 체제 에 의 해 서비스 프로그램 을 강제로 종료 할 수 밖 에 없다.이러한 서비스 프로그램 을 강제로 종료 하 는 방식 은 간단 하고 편리 하지만 서버 에서 실행 중인 작업 이 갑자기 중 단 될 수 있다.서버 가 처리 하 는 작업 이 매우 중요 하 다 면 갑 작 스 럽 게 중단 되 는 것 을 허용 하지 않 고 서버 자체 가 적절 한 시간 에 자신 을 닫 아야 합 니 다.
코드 는 다음 과 같 습 니 다:
EchoServer 클래스

package ShutdownServer;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;

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 serverSocketShutdown;
    private boolean isShutdown=false; //         

    private Thread shutdownThread=new Thread(){
        //          
        public void run(){
            while(!isShutdown){
                Socket socketForShutdown=null;
                try{
                    socketForShutdown=serverSocketShutdown.accept();
                    BufferedReader br=new BufferedReader(
                            new InputStreamReader(socketForShutdown.getInputStream())
                    );
                    String command=br.readLine();
                    if (command.equals("shutdown")){
                        long beginTime=System.currentTimeMillis();
                        socketForShutdown.getOutputStream().write("       \r
".getBytes()); isShutdown=true; // // , executorService.shutdown(); // , 30s // awaitTermination , , 。 // , , awaitTermination() true。 // , , awaitTermination() false。 // , ! // awaitTermination() 。 while(!executorService.isTerminated()) executorService.awaitTermination(30, TimeUnit.SECONDS); // EchoClient ServerSocket serverSocket.close(); long endTime=System.currentTimeMillis(); socketForShutdown.getOutputStream().write((" ,"+" "+(endTime-beginTime)+"ms\r
").getBytes()); socketForShutdown.close(); serverSocketShutdown.close(); System.out.println(" "); } else { socketForShutdown.getOutputStream().write(" \r
".getBytes()); socketForShutdown.close(); } } catch (Exception e) { e.printStackTrace(); } } } }; public EchoServer() throws IOException { serverSocket=new ServerSocket(port); // 60s serverSocket.setSoTimeout(60000); serverSocketShutdown=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 { // SocketTimeoutException SocketException socket=serverSocket.accept(); // 60s socket.setSoTimeout(60000); // RejectedExecutionException executorService.execute(new Handler(socket)); }catch (SocketTimeoutException e){ // }catch (RejectedExecutionException e) { try { if (socket != null) socket.close(); } catch (IOException ex) { return; } }catch (SocketException e){ if (e.getMessage().indexOf("socket closed")!=-1) return; }catch (IOException e){ e.printStackTrace(); } } } public static void main(String[] args) throws IOException { //main , , new EchoServer().service(); } } // class Handler implements Runnable{ private Socket socket; public Handler(Socket socket){ this.socket=socket; } private PrintWriter getWriter(Socket socket) throws IOException{ OutputStream socketOut=socket.getOutputStream(); return new PrintWriter(socketOut,true); } private BufferedReader getReader(Socket socket) throws IOException{ InputStream socketIn=socket.getInputStream(); return new BufferedReader(new InputStreamReader(socketIn)); } public String echo(String msg){ return "echo: "+msg; } @Override public void run() { try{ System.out.println("New connection accepted "+socket.getInetAddress()+":"+socket.getPort()); BufferedReader br=getReader(socket); PrintWriter pw=getWriter(socket); String msg=null; // , while((msg=br.readLine())!=null){ System.out.println("from "+socket.getInetAddress()+":"+socket.getPort()+">"+msg); pw.println(echo(msg)); if (msg.equals("bye")) break; } } catch (IOException e) { e.printStackTrace(); }finally{ try{ if (socket!=null) socket.close(); }catch (IOException e){ e.printStackTrace(); } } } }
  • Admin Client 클래스(EchoServer 에"shutdown"명령 을 보 내 고 서버 를 닫 습 니 다)
  • 
    package ShutdownServer;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class AdminClient {
        public static void main(String[] args){
            Socket socket=null;
            try{
                socket=new Socket("localhost",8001);
                //      
                OutputStream socketOut=socket.getOutputStream();
                //Scanner scanner=new Scanner(System.in);
                //String order=scanner.next();
                socketOut.write("shutdown\r
    ".getBytes()); // BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream())); String msg=null; while ((msg=br.readLine())!=null){ System.out.println(msg); } } catch (Exception e) { e.printStackTrace(); }finally { try{ if (socket!=null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
    클 라 이언 트 클래스(클 라 이언 트,서버 와 통신)
    
    package ShutdownServer;
    
    import java.io.*;
    import java.net.Socket;
    
    public class Client {
        private String host="localhost";
        private int port=8000;
        private Socket socket;
    
        public Client() throws IOException {
            socket=new Socket(host,port);
        }
    
        private PrintWriter getWriter(Socket socket) throws IOException{
            OutputStream socketOut=socket.getOutputStream();
            return new PrintWriter(socketOut,true);
        }
    
        private BufferedReader getReader(Socket socket) throws IOException{
            InputStream socketIn=socket.getInputStream();
            return new BufferedReader(new InputStreamReader(socketIn));
        }
    
        public void talk() throws IOException{
            try{
                BufferedReader br=getReader(socket);
                PrintWriter pw=getWriter(socket);
                BufferedReader localReader=new BufferedReader(new InputStreamReader(System.in));
                String msg=null;
                while((msg=localReader.readLine()) != null){
                    pw.println(msg);
                    System.out.println(br.readLine());
    
                    if (msg.equals("bye")){
                        break;
                    }
                }
            }catch (IOException e){
                e.printStackTrace();
            }
            finally {
                try{
                    socket.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String args[]) throws IOException {
            new Client().talk();
        }
    }
    
    
    shutdown Thread 스 레 드 는 서버 를 닫 는 것 을 담당 합 니 다.8001 포트 를 계속 감청 합 니 다.Admin Client 가 보 낸"shutdown"명령 을 받 으 면 isShutdown 을 true 로 설정 합 니 다.
    서버 를 닫 을 때,우 리 는 가장 자주 사용 하 는 방법 을 사 용 했 습 니 다.먼저 스 레 드 탱크 의 shutdown()방법 을 호출 하고,이어서 스 레 드 탱크 의 awaitTermination()방법 을 호출 합 니 다.
    
    executorService.shutdown();
    
                            //       ,          30s
                            //   awaitTermination ,             ,                      。
                            //              ,             ,  awaitTermination()  true。        
                            //              ,              ,  awaitTermination()  false。         
                            //              ,  !
                            //   awaitTermination()                   。
                            while(!executorService.isTerminated())
                                executorService.awaitTermination(30, TimeUnit.SECONDS);
    
    온라인 스 레 드 탱크 에서 shutdown()방법 을 실행 한 후 스 레 드 탱크 는 새로운 작업 을 받 지 않 습 니 다.또한 이 스 레 드 는 awaitTermination()방법 을 호출 하여 차단 되 었 습 니 다.스 레 드 탱크 의 모든 스 레 드 작업 이 실 행 될 때 까지 이 스 레 드 는 계속 아래로 내 려 갑 니 다.
    실행 결과
    EchoServer,Client,AdminClient 를 먼저 실행 한 후 클 라 이언 트 1 을 열 어 클 라 이언 트 1 이 스 레 드 탱크 에 가입 할 수 없 음 을 표시 합 니 다.
    EchoServer(클 라 이언 트 연결 만 표시 하고 클 라 이언 트 1 에 연결 되 지 않 음)在这里插入图片描述
  • Client
  • 在这里插入图片描述
    클 라 이언 트 2(서버 에 메 시 지 를 보 내 고 null 을 받 음)在这里插入图片描述
  • AdminClient(Client 가 실행 이 끝나 지 않 았 을 때 차단 됨)
  • 在这里插入图片描述
    클 라 이언 트 가"bye"를 입력 하고 실행 이 끝나 면 AdminClient 가 서버 를 닫 습 니 다.
    Client 클래스
    在这里插入图片描述
    EchoServer 클래스在这里插入图片描述
    Admin Client 클래스在这里插入图片描述
    자바 네트워크 프로 그래 밍 핵심 기술 상세 참조
    JAVA 를 이용 하여 자체 적 으로 서버 를 닫 을 수 있 는 방법 을 알려 드 리 는 이 글 은 여기까지 입 니 다.더 많은 JAVA 자체 적 으로 서버 를 닫 는 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 읽 어 주시 기 바 랍 니 다.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!

    좋은 웹페이지 즐겨찾기