WEB服务器启动时加载一个ServerSocket服务

来源:互联网 发布:网络电视哪个好 编辑:程序博客网 时间:2024/06/04 18:37

       如果在项目中需要让一个ServerSocket服务伴随WEB服务器的启动而启动,时刻监控某个端口,接收Socket客户端发送过来的socket报文。需要做以下配置,配置完成后程序支持随服务器启动,支持同时处理多个socket客户端请求。

      1.配置web.xml
在web.xml的节点中添加以下内容:
<context-param>
<param-name>socketPort</param-name><param-value>3800</param-value></context-param><listener>
<description>Socket服务随web启动而启动</description>
<listener-class>service.ServerSocketListener</listener-class></listener>注:网上也有人提出可以使用servlet节点进行配置,具体如下:
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>service.ServerSocketServlet</servlet-class><load-on-startup>3</load-on-startup></servlet>这样做有一个很大的问题,就是服务器关闭时资源无法得到完全释放,端口可能仍然被占用
    2.编写监听器Listener中配置的类
ServerSocketListener类需要实现ServletContextListener
publicclassServerSocketListenerimplementsServletContextListener{
privateSocketThreadsocketThread;
publicvoidcontextDestroyed(ServletContextEvente){
if(socketThread!=null&&socketThread.isInterrupted()){
socketThread.closeServerSocket();socketThread.interrupt();}}
publicvoidcontextInitialized(ServletContextEvente){
ServletContextservletContext=e.getServletContext();if(str==null&&socketThread==null){
socketThread=newSocketThread(null,servletContext);
socketThread.start();//servlet上下文初始化时启动socket服务端线程
}}}
/**
*自定义一个Socket线程类继承自线程类,重写run()方法,用于接收客户端socket请求报文*/
classSocketThreadextendsThread{
privateServletContextservletContext;privateServerSocketserverSocket;
publicSocketThread(ServerSocketserverSocket,ServletContextservletContext){
this.servletContext=servletContext;//从web.xml中context-param节点获取socket端口
Stringport=this.servletContext.getInitParameter("socketPort");if(serverSocket==null){
try{
this.serverSocket=newServerSocket(Integer.parseInt(port));}catch(IOExceptione){
e.printStackTrace();}}}
publicvoidrun(){
while(!this.isInterrupted()){//线程未中断执行循环
try{
Socketsocket=serverSocket.accept();if(socket!=null)
newProcessSocketData(socket,this.servletContext).start();
}catch(IOExceptione){
e.printStackTrace();}}}
publicvoidcloseServerSocket(){
try{
if(serverSocket!=null&&!serverSocket.isClosed())
serverSocket.close();
}catch(IOExceptione){
e.printStackTrace();}}}


     Socket消息报文处理类
classProcessSocketDataextendsThread{
privateSocketsocket;
privateServletContextservletContext;publicProcessSocketData(){
super();}
publicProcessSocketData(Socketsocket,ServletContextservletContext){
this.socket=socket;
this.servletContext=servletContext;}
publicvoidrun(){
try{
BufferedReaderbr=newBufferedReader(newInputStreamReader(
socket.getInputStream()));
PrintWriterpw=newPrintWriter(socket.getOutputStream());Stringrequest=br.readLine();//从流中读取请求消息报文//执行自定义的请求解析方法,生成响应responsepw.println(response);pw.flush();//刷新缓冲区}catch(IOExceptione){
e.printStackTrace();}}}
      3.一个简单的Socket客户端,用于验证以上程序
publicclassTestClient

{
publicvoidcreateSocketClient(Stringhost,intport)

{
Socketsocket=null;PrintWriterpw=null;BufferedReaderbr=null;try

{
Stringrequest="20110624";socket=newSocket(host,port);
pw=newPrintWriter(newOutputStreamWriter(socket.getOutputStream()));pw.println(request[i]);pw.flush();
br=newBufferedReader(newInputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());}catch(Exceptione){
e.printStackTrace();}
}
publicstaticvoidmain(String[]args){
TestClientclient=newTestClient();
client.createSocketClient("127.0.0.1",3800);}}

0 0