最近在作一个APP的服务器端,可是APP和服务器端使用的是HTTP的通讯协议,而另外一方与服务器端通讯却使用的是自定义的通讯协议。具体的系统拓扑以下:java
为了完成以上的需求,通常的解决方案有两种:web
本身实现服务器端程序,利用已经实现的http jar包来实现http通讯协议,同时利用socket通讯来实现本身的通讯协议;tomcat
将socket通讯整合在tomcat中,利用tomcat来提供http通讯,同时实现本身的通讯协议。服务器
对于第一种方法,全部的都须要本身来实现,须要本身进行环境的初始化,配置管理,比较麻烦。目前为了方便开发,快速利用web的各类框架,采用的是第二种方法,将socket通讯整合在tomcat环境下,随着web的启动,初始化一个socketserver来进行自定义的数据通讯。app
在web环境下,tomcat整合socket的主要的难处就是如何触发socket服务器的初始化,等待接受来自客户端的链接,且socket服务器的初始化应该只初始化一次。在web启动的时候,toncat会加载 context-param -> listener -> filter -> servlet,因此就能够在这些类中来初始化socket服务来进行通讯。因而就新建一个SocketServlet并在框架
public void init(ServletConfig config) throws ServletException
方法中初始化一个ECHO Server的SocketServer来进行通讯socket
// TODO Auto-generated method stub System.out.println("this is the socket program ----zhangwenwen"); try { ServerSocket serverSocket=new ServerSocket(8191); socket=serverSocket.accept(); InputStream inputStream=socket.getInputStream(); OutputStream outputStream=socket.getOutputStream(); Scanner in=new Scanner(inputStream); PrintWriter printWriter=new PrintWriter(outputStream); printWriter.write("Hello Enter BYE to exit!"); boolean done=false; while(!done&&in.hasNextLine()){ String line=in.nextLine(); System.out.println(line); printWriter.println("ECHO:"+line); printWriter.flush(); if (line.trim().equals("BYE")) { done=true; } } in.close(); inputStream.close(); outputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
在web.xml中配置:ide
<servlet> <servlet-name>socketdemo</servlet-name> <servlet-class>SocketServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>socketdemo</servlet-name> <url-pattern>/demo</url-pattern> </servlet-mapping>
可是在启动时候却由于SocketServer一直在运行,Init方法运行不能返回,从而ServletSocket不能运行结束,tomcat最后会由于启动失败而退出。ui
于是,如今为了解决这个问题,因而就将SocketServer封装在一个线程中this
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; import javax.servlet.annotation.WebFilter; import sun.print.resources.serviceui; public class SocketDemo extends Thread { private static Socket socket=null; public static Socket getSocket() { return socket; } @Override public void run() { // TODO Auto-generated method stub System.out.println("this is the socket program ----zhangwenwen"); try { ServerSocket serverSocket=new ServerSocket(8191); socket=serverSocket.accept(); InputStream inputStream=socket.getInputStream(); OutputStream outputStream=socket.getOutputStream(); Scanner in=new Scanner(inputStream); PrintWriter printWriter=new PrintWriter(outputStream); printWriter.write("Hello Enter BYE to exit!\n"); printWriter.flush(); boolean done=false; while(!done&&in.hasNextLine()){ String line=in.nextLine(); System.out.println(line); printWriter.println("ECHO:"+line); printWriter.flush(); if (line.trim().equals("BYE")) { done=true; } } in.close(); inputStream.close(); outputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
而后在Init方法里面在启动一个线程来初始化SocketServer:
/** * @see Servlet#init(ServletConfig) */ public void init(ServletConfig config) throws ServletException { SocketDemo socketDemo=new SocketDemo(); socketDemo.start(); this.socket=socketDemo.getSocket(); }
这样就实现了在tomcat下进行,在控制台下用telnet进行访问: