此文中例子为:一个在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();
}
}
}