亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

How Tomcat Works(十七)

系統(tǒng) 2076 0

在前面的文章中,已經(jīng)學(xué)會(huì)了如何通過(guò)實(shí)例化一個(gè)連接器和容器來(lái)獲得一個(gè)servlet容器,并將連接器和容器相關(guān)聯(lián);但在前面的文章中只有一個(gè)連接器可用,該連接器服務(wù)8080端口上的HTTP請(qǐng)求,無(wú)法添加另一個(gè)連接器來(lái)服務(wù)諸如HTTPS之類的其他請(qǐng)求;此外,在前面的文章中的應(yīng)用程序中有些缺憾,即缺少一種啟動(dòng)/關(guān)閉servlet容器的機(jī)制。

org.apache.catalina.Server接口的實(shí)例表示Catalina的整個(gè)servlet引擎,囊括了所有的組件;它使用一個(gè)優(yōu)雅的方式來(lái)啟動(dòng)/關(guān)閉整個(gè)系統(tǒng),不需要再對(duì)連接器和容器分別啟動(dòng)/關(guān)閉(當(dāng)啟動(dòng)Server組件時(shí),它會(huì)啟動(dòng)其中所有的組件,然后它就無(wú)限期地等待關(guān)閉命令;如果想要關(guān)閉系統(tǒng),可以向指定端口發(fā)送一條關(guān)閉命令,Server組件接收到關(guān)閉命令后,就會(huì)關(guān)閉其中所有的組件)。

Server組件使用了另一個(gè)組件(即Service組件)來(lái)包含其他組件,如一個(gè)容器組件和一個(gè)或多個(gè)連接器組件。

下面是Server接口的定義

      
        public
      
      
        interface
      
      
         Server {
   
      
      
        public
      
      
         String getInfo();
    
      
      
        public
      
      
         NamingResources getGlobalNamingResources();
   
      
      
        public
      
      
        void
      
      
         setGlobalNamingResources(NamingResources globalNamingResources);
   
      
      
        public
      
      
        int
      
      
         getPort();
   
      
      
        public
      
      
        void
      
       setPort(
      
        int
      
      
         port);
    
      
      
        public
      
      
         String getShutdown();
   
      
      
        public
      
      
        void
      
      
         setShutdown(String shutdown);
   
      
      
        public
      
      
        void
      
      
         addService(Service service);
    
      
      
        public
      
      
        void
      
      
         await();
    
      
      
        public
      
      
         Service findService(String name);
    
      
      
        public
      
      
         Service[] findServices();
   
      
      
        public
      
      
        void
      
      
         removeService(Service service);
   
      
      
        public
      
      
        void
      
      
         initialize()   
      
      
        throws
      
      
         LifecycleException;
}
      
    

shutdown屬性保存了必須發(fā)送給Server實(shí)例用來(lái)關(guān)閉整個(gè)系統(tǒng)的關(guān)閉命令,port屬性定義了Server組件會(huì)從哪個(gè)端口獲取關(guān)閉命令,可以調(diào)用addService()方法為Server組件添加Service組件,或通過(guò)removeService()方法刪除某個(gè)Service組件,findService()方法將會(huì)返回添加到該Server組件中的所有Service組件,initialize()方法包含在系統(tǒng)啟動(dòng)前要執(zhí)行的一些代碼

?org.apache.catalina.core.StandardServer類是Server接口的標(biāo)準(zhǔn)實(shí)現(xiàn),介紹這個(gè)類是因?yàn)槲覀儗?duì)其中的關(guān)閉機(jī)制比較感興趣,而這也是這個(gè)類中最重要的特性;該類的許多方法都與新server.xml文件中的服務(wù)器配置的存儲(chǔ)相關(guān),但這并不是本文的重點(diǎn)。

一個(gè)Server組件可以有多個(gè)Service組件,StandardServer類提供了addService()方法、 removeService()方法和findServices()方法的實(shí)現(xiàn)

StandardServer類有四個(gè)與生命周期相關(guān)的方法,分別是initialize()方法、 start()方法、 stop()方法和await()方法,就像其他組件一樣,可以初始化并啟動(dòng)Server組件,然后調(diào)用await()方法及stop()方法。調(diào)用await()方法后會(huì)一直阻塞住,直到它總8085端口上接收到關(guān)閉命令。當(dāng)await()方法返回時(shí),會(huì)運(yùn)行stop()方法來(lái)關(guān)閉其下的所有子組件。

Server實(shí)例的initialize()方法用于初始化添加到其中的Service組件,下面是tomcat4中StandardServer類中initialize()方法的實(shí)現(xiàn)

      
        public
      
      
        void
      
       initialize()    
      
        throws
      
      
         LifecycleException {
        
      
      
        if
      
      
         (initialized)
            
      
      
        throw
      
      
        new
      
      
         LifecycleException (
                sm.getString(
      
      "standardServer.initialize.initialized"
      
        ));
        initialized 
      
      = 
      
        true
      
      
        ;

        
      
      
        //
      
      
         Initialize our defined Services
      
      
        for
      
       (
      
        int
      
       i = 0; i < services.length; i++
      
        ) {
            services[i].initialize();
        }
    }
      
    

start()方法用于啟動(dòng)Server組件,在StandardServer類的start()方法的實(shí)現(xiàn)中,它會(huì)啟動(dòng)其所有的Service組件,這些Service組件它們逐個(gè)啟動(dòng)所有其他的組件,如連接器組件和servlet容器。

      
        public
      
      
        void
      
       start() 
      
        throws
      
      
         LifecycleException {

        
      
      
        //
      
      
         Validate and update our current component state
      
      
        if
      
      
         (started)
            
      
      
        throw
      
      
        new
      
      
         LifecycleException
                (sm.getString(
      
      "standardServer.start.started"
      
        ));
        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, 
      
        null
      
      
        );

        lifecycle.fireLifecycleEvent(START_EVENT, 
      
      
        null
      
      
        );
        started 
      
      = 
      
        true
      
      
        ;

        
      
      
        //
      
      
         Start our defined Services
      
      
        synchronized
      
      
         (services) {
            
      
      
        for
      
       (
      
        int
      
       i = 0; i < services.length; i++
      
        ) {
                
      
      
        if
      
       (services[i] 
      
        instanceof
      
      
         Lifecycle)
                    ((Lifecycle) services[i]).start();
            }
        }

        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, 
      
        null
      
      
        );

    }
      
    

stop()方法用于關(guān)閉Server組件

      
        public
      
      
        void
      
       stop() 
      
        throws
      
      
         LifecycleException {

        
      
      
        //
      
      
         Validate and update our current component state
      
      
        if
      
       (!
      
        started)
            
      
      
        throw
      
      
        new
      
      
         LifecycleException
                (sm.getString(
      
      "standardServer.stop.notStarted"
      
        ));

        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, 
      
        null
      
      
        );

        lifecycle.fireLifecycleEvent(STOP_EVENT, 
      
      
        null
      
      
        );
        started 
      
      = 
      
        false
      
      
        ;

        
      
      
        //
      
      
         Stop our defined Services
      
      
        for
      
       (
      
        int
      
       i = 0; i < services.length; i++
      
        ) {
            
      
      
        if
      
       (services[i] 
      
        instanceof
      
      
         Lifecycle)
                ((Lifecycle) services[i]).stop();
        }

        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, 
      
        null
      
      
        );

    }
      
    

await()方法負(fù)責(zé)停止整個(gè)tomcat部署的機(jī)制

      
        /**
      
      
        
     * Wait until a proper shutdown command is received, then return.
     
      
      
        */
      
      
        public
      
      
        void
      
      
         await() {

        
      
      
        //
      
      
         Set up a server socket to wait on
      
      
        ServerSocket serverSocket = 
      
        null
      
      
        ;
        
      
      
        try
      
      
         {
            serverSocket 
      
      =
                
      
        new
      
       ServerSocket(port, 1
      
        ,
                                 InetAddress.getByName(
      
      "127.0.0.1"
      
        ));
        } 
      
      
        catch
      
      
         (IOException e) {
            System.err.println(
      
      "StandardServer.await: create[" +
      
         port
                               
      
      + "]: " +
      
         e);
            e.printStackTrace();
            System.exit(
      
      1
      
        );
        }

        
      
      
        //
      
      
         Loop waiting for a connection and a valid command
      
      
        while
      
       (
      
        true
      
      
        ) {

            
      
      
        //
      
      
         Wait for the next connection
      
      
            Socket socket = 
      
        null
      
      
        ;
            InputStream stream 
      
      = 
      
        null
      
      
        ;
            
      
      
        try
      
      
         {
                socket 
      
      =
      
         serverSocket.accept();
                socket.setSoTimeout(
      
      10 * 1000);  
      
        //
      
      
         Ten seconds
      
      
                stream =
      
         socket.getInputStream();
            } 
      
      
        catch
      
      
         (AccessControlException ace) {
                System.err.println(
      
      "StandardServer.accept security exception: "
                                   +
      
         ace.getMessage());
                
      
      
        continue
      
      
        ;
            } 
      
      
        catch
      
      
         (IOException e) {
                System.err.println(
      
      "StandardServer.await: accept: " +
      
         e);
                e.printStackTrace();
                System.exit(
      
      1
      
        );
            }

            
      
      
        //
      
      
         Read a set of characters from the socket
      
      
            StringBuffer command = 
      
        new
      
      
         StringBuffer();
            
      
      
        int
      
       expected = 1024; 
      
        //
      
      
         Cut off to avoid DoS attack
      
      
        while
      
       (expected <
      
         shutdown.length()) {
                
      
      
        if
      
       (random == 
      
        null
      
      
        )
                    random 
      
      = 
      
        new
      
      
         Random(System.currentTimeMillis());
                expected 
      
      += (random.nextInt() % 1024
      
        );
            }
            
      
      
        while
      
       (expected > 0
      
        ) {
                
      
      
        int
      
       ch = -1
      
        ;
                
      
      
        try
      
      
         {
                    ch 
      
      =
      
         stream.read();
                } 
      
      
        catch
      
      
         (IOException e) {
                    System.err.println(
      
      "StandardServer.await: read: " +
      
         e);
                    e.printStackTrace();
                    ch 
      
      = -1
      
        ;
                }
                
      
      
        if
      
       (ch < 32)  
      
        //
      
      
         Control character or EOF terminates loop
      
      
        break
      
      
        ;
                command.append((
      
      
        char
      
      
        ) ch);
                expected
      
      --
      
        ;
            }

            
      
      
        //
      
      
         Close the socket now that we are done with it
      
      
        try
      
      
         {
                socket.close();
            } 
      
      
        catch
      
      
         (IOException e) {
                ;
            }

            
      
      
        //
      
      
         Match against our command string
      
      
        boolean
      
       match =
      
         command.toString().equals(shutdown);
            
      
      
        if
      
      
         (match) {
                
      
      
        break
      
      
        ;
            } 
      
      
        else
      
      
        
                System.err.println(
      
      "StandardServer.await: Invalid command '" +
      
        
                                   command.toString() 
      
      + "' received"
      
        );

        }

        
      
      
        //
      
      
         Close the server socket and return
      
      
        try
      
      
         {
            serverSocket.close();
        } 
      
      
        catch
      
      
         (IOException e) {
            ;
        }

    }
      
    

await()方法創(chuàng)建一個(gè)ServerSocket對(duì)象,監(jiān)聽8085端口,并在while循環(huán)中調(diào)用它的accept()方法,擋在指定端口上接收到消息時(shí),才會(huì)從accept()方法中返回,然后將接收到的消息與關(guān)閉命令的字符串相比較,相同的話就跳出while循環(huán),關(guān)閉ServerSocket,否則會(huì)再次循環(huán),繼續(xù)等待消息。

Service組件是org.apache.catalina.Service接口的實(shí)例,一個(gè)Service組件可以有一個(gè)servlet容器和多個(gè)連接器實(shí)例,可以自由地把連接器實(shí)例添加到Service組件中,所有的連接器都會(huì)與該servlet容器相關(guān)聯(lián)

下面是Service接口的定義

      
        public
      
      
        interface
      
      
         Service {
   
      
      
        public
      
      
         Container getContainer();
  
      
      
        public
      
      
        void
      
      
         setContainer(Container container);
   
      
      
        public
      
      
         String getInfo();
   
      
      
        public
      
      
         String getName();
    
      
      
        public
      
      
        void
      
      
         setName(String name);
   
      
      
        public
      
      
         Server getServer();
   
      
      
        public
      
      
        void
      
      
         setServer(Server server);    
   
      
      
        public
      
      
        void
      
      
         addConnector(Connector connector);
   
      
      
        public
      
      
         Connector[] findConnectors();
   
      
      
        public
      
      
        void
      
      
         removeConnector(Connector connector);
   
      
      
        public
      
      
        void
      
      
         initialize()   
      
      
        throws
      
      
         LifecycleException;
}
      
    

org.apache.catalina.core.StandardService類是Service接口的標(biāo)準(zhǔn)實(shí)現(xiàn),StandardService類的initialize()方法用于初始化添加到其中的所有連接器;此外,還實(shí)現(xiàn)了org.apache.catalina.Lifecycle接口,它的start()方法用于啟動(dòng)servlet容器和所有連接器

StandardService實(shí)例中有兩種組件,分別是連接器和servlet容器,其中servlet容器只有一個(gè),而連接器則可以有多個(gè),多個(gè)連接器使tomcat可以為多種不同的請(qǐng)求協(xié)議提供服務(wù)。例如,一個(gè)連接器處理HTTP請(qǐng)求,而另一個(gè)可以處理HTTPS請(qǐng)求。

StandardService類使用變量container來(lái)指向一個(gè)Container接口的實(shí)例,使用數(shù)組connectors來(lái)保存所有連接器的引用

private Container container = null;

private Connector connectors[] = new Connector[0];

需要調(diào)用setContainer()方法將servlet容器與Service組件相關(guān)聯(lián):

      
        public
      
      
        void
      
      
         setContainer(Container container) {

        Container oldContainer 
      
      = 
      
        this
      
      
        .container;
        
      
      
        if
      
       ((oldContainer != 
      
        null
      
      ) && (oldContainer 
      
        instanceof
      
      
         Engine))
            ((Engine) oldContainer).setService(
      
      
        null
      
      
        );
        
      
      
        this
      
      .container =
      
         container;
        
      
      
        if
      
       ((
      
        this
      
      .container != 
      
        null
      
      ) && (
      
        this
      
      .container 
      
        instanceof
      
      
         Engine))
            ((Engine) 
      
      
        this
      
      .container).setService(
      
        this
      
      
        );
        
      
      
        if
      
       (started && (
      
        this
      
      .container != 
      
        null
      
      ) &&
      
        
            (
      
      
        this
      
      .container 
      
        instanceof
      
      
         Lifecycle)) {
            
      
      
        try
      
      
         {
                ((Lifecycle) 
      
      
        this
      
      
        .container).start();
            } 
      
      
        catch
      
      
         (LifecycleException e) {
                ;
            }
        }
        
      
      
        synchronized
      
      
         (connectors) {
            
      
      
        for
      
       (
      
        int
      
       i = 0; i < connectors.length; i++
      
        )
                connectors[i].setContainer(
      
      
        this
      
      
        .container);
        }
        
      
      
        if
      
       (started && (oldContainer != 
      
        null
      
      ) &&
      
        
            (oldContainer 
      
      
        instanceof
      
      
         Lifecycle)) {
            
      
      
        try
      
      
         {
                ((Lifecycle) oldContainer).stop();
            } 
      
      
        catch
      
      
         (LifecycleException e) {
                ;
            }
        }

        
      
      
        //
      
      
         Report this property change to interested listeners
      
      
        support.firePropertyChange("container", oldContainer, 
      
        this
      
      
        .container);

    }
      
    

與Service組件相關(guān)聯(lián)的servlet容器的實(shí)例將被傳給每個(gè)連接器對(duì)象的setContainer()方法,這樣在Service組件中就可以形成每個(gè)連接器和servlet容器之間的關(guān)聯(lián)關(guān)系。

可以調(diào)用addConnector()方法將連接器添加到Service組件中,調(diào)用removeConnector()方法將某個(gè)連接器移除

      
        public
      
      
        void
      
      
         addConnector(Connector connector) {

        
      
      
        synchronized
      
      
         (connectors) {
            connector.setContainer(
      
      
        this
      
      
        .container);
            connector.setService(
      
      
        this
      
      
        );
            Connector results[] 
      
      = 
      
        new
      
       Connector[connectors.length + 1
      
        ];
            System.arraycopy(connectors, 
      
      0, results, 0
      
        , connectors.length);
            results[connectors.length] 
      
      =
      
         connector;
            connectors 
      
      =
      
         results;

            
      
      
        if
      
      
         (initialized) {
                
      
      
        try
      
      
         {
                    connector.initialize();
                } 
      
      
        catch
      
      
         (LifecycleException e) {
                    e.printStackTrace(System.err);
                }
            }

            
      
      
        if
      
       (started && (connector 
      
        instanceof
      
      
         Lifecycle)) {
                
      
      
        try
      
      
         {
                    ((Lifecycle) connector).start();
                } 
      
      
        catch
      
      
         (LifecycleException e) {
                    ;
                }
            }

            
      
      
        //
      
      
         Report this property change to interested listeners
      
      
            support.firePropertyChange("connector", 
      
        null
      
      
        , connector);
        }

    }
      
    

在上面方法中,會(huì)初始化并啟動(dòng)添加到其中的連接器。

      
        public
      
      
        void
      
      
         removeConnector(Connector connector) {

        
      
      
        synchronized
      
      
         (connectors) {
            
      
      
        int
      
       j = -1
      
        ;
            
      
      
        for
      
       (
      
        int
      
       i = 0; i < connectors.length; i++
      
        ) {
                
      
      
        if
      
       (connector ==
      
         connectors[i]) {
                    j 
      
      =
      
         i;
                    
      
      
        break
      
      
        ;
                }
            }
            
      
      
        if
      
       (j < 0
      
        )
                
      
      
        return
      
      
        ;
            
      
      
        if
      
       (started && (connectors[j] 
      
        instanceof
      
      
         Lifecycle)) {
                
      
      
        try
      
      
         {
                    ((Lifecycle) connectors[j]).stop();
                } 
      
      
        catch
      
      
         (LifecycleException e) {
                    ;
                }
            }
            connectors[j].setContainer(
      
      
        null
      
      
        );
            connector.setService(
      
      
        null
      
      
        );
            
      
      
        int
      
       k = 0
      
        ;
            Connector results[] 
      
      = 
      
        new
      
       Connector[connectors.length - 1
      
        ];
            
      
      
        for
      
       (
      
        int
      
       i = 0; i < connectors.length; i++
      
        ) {
                
      
      
        if
      
       (i !=
      
         j)
                    results[k
      
      ++] =
      
         connectors[i];
            }
            connectors 
      
      =
      
         results;

            
      
      
        //
      
      
         Report this property change to interested listeners
      
      
            support.firePropertyChange("connector", connector, 
      
        null
      
      
        );
        }

    }
      
    

與生命周期相關(guān)的方法包括從Lifecycle接口中實(shí)現(xiàn)的start()方法和stop()方法,在加上initialize()方法,其中initialize()方法會(huì)調(diào)用該Service組件中所有連接器的上initialize()方法:

      
        public
      
      
        void
      
       initialize()  
      
        throws
      
      
         LifecycleException {
        
      
      
        if
      
      
         (initialized)
            
      
      
        throw
      
      
        new
      
      
         LifecycleException (
                sm.getString(
      
      "standardService.initialize.initialized"
      
        ));
        initialized 
      
      = 
      
        true
      
      
        ;

        
      
      
        //
      
      
         Initialize our defined Connectors
      
      
        synchronized
      
      
         (connectors) {
                
      
      
        for
      
       (
      
        int
      
       i = 0; i < connectors.length; i++
      
        ) {
                    connectors[i].initialize();
                }
        }
    }
      
    

start()方法負(fù)責(zé)啟動(dòng)被添加到該Service組件中的連接器和servlet容器:

      
        public
      
      
        void
      
       start() 
      
        throws
      
      
         LifecycleException {

        
      
      
        //
      
      
         Validate and update our current component state
      
      
        if
      
      
         (started) {
            
      
      
        throw
      
      
        new
      
      
         LifecycleException
                (sm.getString(
      
      "standardService.start.started"
      
        ));
        }

        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, 
      
        null
      
      
        );

        System.out.println
            (sm.getString(
      
      "standardService.start.name", 
      
        this
      
      
        .name));
        lifecycle.fireLifecycleEvent(START_EVENT, 
      
      
        null
      
      
        );
        started 
      
      = 
      
        true
      
      
        ;

        
      
      
        //
      
      
         Start our defined Container first
      
      
        if
      
       (container != 
      
        null
      
      
        ) {
            
      
      
        synchronized
      
      
         (container) {
                
      
      
        if
      
       (container 
      
        instanceof
      
      
         Lifecycle) {
                    ((Lifecycle) container).start();
                }
            }
        }

        
      
      
        //
      
      
         Start our defined Connectors second
      
      
        synchronized
      
      
         (connectors) {
            
      
      
        for
      
       (
      
        int
      
       i = 0; i < connectors.length; i++
      
        ) {
                
      
      
        if
      
       (connectors[i] 
      
        instanceof
      
      
         Lifecycle)
                    ((Lifecycle) connectors[i]).start();
            }
        }

        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, 
      
        null
      
      
        );

    }
      
    

stop()方法用于關(guān)閉與該Service組件相關(guān)聯(lián)的servlet容器和所有連接器

      
        public
      
      
        void
      
       stop() 
      
        throws
      
      
         LifecycleException {

        
      
      
        //
      
      
         Validate and update our current component state
      
      
        if
      
       (!
      
        started) {
            
      
      
        throw
      
      
        new
      
      
         LifecycleException
                (sm.getString(
      
      "standardService.stop.notStarted"
      
        ));
        }

        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, 
      
        null
      
      
        );

        lifecycle.fireLifecycleEvent(STOP_EVENT, 
      
      
        null
      
      
        );

        System.out.println
            (sm.getString(
      
      "standardService.stop.name", 
      
        this
      
      
        .name));
        started 
      
      = 
      
        false
      
      
        ;

        
      
      
        //
      
      
         Stop our defined Connectors first
      
      
        synchronized
      
      
         (connectors) {
            
      
      
        for
      
       (
      
        int
      
       i = 0; i < connectors.length; i++
      
        ) {
                
      
      
        if
      
       (connectors[i] 
      
        instanceof
      
      
         Lifecycle)
                    ((Lifecycle) connectors[i]).stop();
            }
        }

        
      
      
        //
      
      
         Stop our defined Container second
      
      
        if
      
       (container != 
      
        null
      
      
        ) {
            
      
      
        synchronized
      
      
         (container) {
                
      
      
        if
      
       (container 
      
        instanceof
      
      
         Lifecycle) {
                    ((Lifecycle) container).stop();
                }
            }
        }

        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, 
      
        null
      
      
        );

    }
      
    

在前面文章的應(yīng)用程序中,通過(guò)按某個(gè)鍵或強(qiáng)制中斷的方式關(guān)閉servlet容器,Stopper類提供了一種更優(yōu)雅的方式來(lái)關(guān)閉Catalina服務(wù)器;此外,它也保證了所有的生命周期組件的stop()方法都能夠調(diào)用。

      
        public
      
      
        class
      
      
         Stopper {

  
      
      
        public
      
      
        static
      
      
        void
      
      
         main(String[] args) {
    
      
      
        //
      
      
         the following code is taken from the Stop method of
    
      
      
        //
      
      
         the org.apache.catalina.startup.Catalina class
      
      
        int
      
       port = 8005
      
        ;
    
      
      
        try
      
      
         {
      Socket socket 
      
      = 
      
        new
      
       Socket("127.0.0.1"
      
        , port);
      OutputStream stream 
      
      =
      
         socket.getOutputStream();
      String shutdown 
      
      = "SHUTDOWN"
      
        ;
      
      
      
        for
      
       (
      
        int
      
       i = 0; i < shutdown.length(); i++
      
        )
        stream.write(shutdown.charAt(i));
      stream.flush();
      stream.close();
      socket.close();
      System.out.println(
      
      "The server was successfully shut down."
      
        );
    }
    
      
      
        catch
      
      
         (IOException e) {
      System.out.println(
      
      "Error. The server has not been started."
      
        );
    }
  }
}
      
    

---------------------------------------------------------------------------?

本系列How Tomcat Works系本人原創(chuàng)?

轉(zhuǎn)載請(qǐng)注明出處 博客園 刺猬的溫馴?

本人郵箱: ? chenying998179 # 163.com ( #改為@

本文鏈接 http://www.cnblogs.com/chenying99/p/3249158.html

How Tomcat Works(十七)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 四虎成人永久地址 | 久久综合久久综合久久综合 | 欧美在线成人午夜影视 | 欧美一区二区三区成人看不卡 | 国产高清ujzzujzz | 天天操精品视频 | 欧美综合网| 中文字幕色婷婷在线视频 | 奶交性视频欧美 | 欧美成人香蕉在线观看 | 亚洲黄色成人 | 国内精品免费一区二区三区 | 欧美一区二区三区不卡片 | 亚洲国产精品综合一区在线 | 免费观看性欧美毛片 | 欧美午夜在线 | 日本一级爽毛片在线看 | 国产伦精品一区二区三区无广告 | 97影院在线观看 | 久草在线看片 | 免费看搡女人的视频 | 国产伦精品一区二区三区免费观看 | 五月婷婷在线观看视频 | 国产成人精品福利色多多 | 亚洲人成影院午夜网站 | 免费在线观看一级片 | 久久久久香蕉视频 | 黄页在线播放网址 | 日本高清不卡在线观看 | 成年女人a毛片免费视频 | 久久社区视频 | 久久一本色道综合 | 欧美一区二区日韩一区二区 | 国产伦精品一区二区三区女 | 久久成人免费视频 | 午夜骚 | 欧美123区| 亚洲综合国产 | 就要爱综合| 亚洲国产日韩欧美综合久久 | 亚洲91av|