tomcat中ServerSocket监听一个端口的探讨

此文中例子为:一个在B/S应用,应用中,需要对远程请求进行连接,并接收他传来的数据。应用中使用了一个ServerSocket建立一个侦听端口,远程请求向此端口发出信息,并建立连接,接收数据。侦听是在应用中配置一个listener,tomcat启动时,就打开一个线程来侦听端口,程序代码如下:

import java.net.*; import java.io.*; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class SocketListener implements ServletContextListener { Processor p = new Processor(); public void contextDestroyed(ServletContextEvent arg0) { } public void contextInitialized(ServletContextEvent arg0) { p.start(); } } class Processor extends Thread { Socket s = null; ServerSocket socket = null; public void run() { try { socket = new ServerSocket(15000); // 在15000端口监听 while(true){ System.out.println("在处理"); System.out.println("前"); s = socket.accept(); System.out.println("后"); } } catch (Exception e) { e.printStackTrace(); } finally{ try { System.out.println("s="+s); if(s!=null)s.close(); if(socket!=null)socket.close(); System.out.print("socket已经关闭!!!"); } catch (IOException e) { e.printStackTrace(); } } } }

此类在侦听启动后,如果在tomcat中安装一个probe用来管理应用,这时就会遇到无法关闭此端口的问题。

具体情况是:使用probe关闭含有上述功能的应用,再打开时,会报端口绑定异常,经查是侦听端口没有关闭所致,但为什么会这样呢?原因出在while(true){}循环是一个没有终止功能,即无法停止所在线程和端口侦听,因为采用上述方法关闭应用时无法执行finally中的socket关闭语句,程序会在socket.accept()处阻塞,直到有到此端口的请求,获得一个socket,完毕后,程序会再次被socket.accept()阻塞,关闭应用不关闭tomcat的情况下,线程是不是退出,从而也就不会关闭侦听端口,修改后的程序如下:

import java.net.*; import java.io.*; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class SocketListener implements ServletContextListener { Processor p = new Processor(); public void contextDestroyed(ServletContextEvent arg0) { p.closet(); System.out.print("我反线程关闭标识置false!"); } public void contextInitialized(ServletContextEvent arg0) { p.start(); } } class Processor extends Thread { Socket s = null; ServerSocket socket = null; public void run() { try { socket = new ServerSocket(15000); // 在15000端口监听 while(true){ System.out.println("在处理"); System.out.println("前"); s = socket.accept(); System.out.println("后"); } } catch (Exception e) { e.printStackTrace(); } finally{ } } public void closet(){ try { System.out.println("s="+s); if(s!=null)s.close(); if(socket!=null)socket.close(); this.stop(); System.out.print("socket已经关闭!!!"); } catch (IOException e) { e.printStackTrace(); } } }

你可能感兴趣的:(JAVA)