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();
}
}
}
}
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 에 연결 되 지 않 음)
클 라 이언 트 2(서버 에 메 시 지 를 보 내 고 null 을 받 음)
클 라 이언 트 가"bye"를 입력 하고 실행 이 끝나 면 AdminClient 가 서버 를 닫 습 니 다.
Client 클래스
EchoServer 클래스
Admin Client 클래스
자바 네트워크 프로 그래 밍 핵심 기술 상세 참조
JAVA 를 이용 하여 자체 적 으로 서버 를 닫 을 수 있 는 방법 을 알려 드 리 는 이 글 은 여기까지 입 니 다.더 많은 JAVA 자체 적 으로 서버 를 닫 는 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 읽 어 주시 기 바 랍 니 다.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA 객체 작성 및 제거 방법정적 공장 방법 정적 공장 방법의 장점 를 반환할 수 있습니다. 정적 공장 방법의 단점 류 공유되거나 보호된 구조기를 포함하지 않으면 이불류화할 수 없음 여러 개의 구조기 파라미터를 만났을 때 구축기를 고려해야 한다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.