最近在做一个APP的服务器端,但是APP和服务器端使用的是HTTP的通信协议,而另一方与服务器端通信却使用的是自定义的通信协议。具体的系统拓扑如下:
为了完成以上的需求,一般的解决方案有两种:
自己实现服务器端程序,利用已经实现的http jar包来实现http通信协议,同时利用socket通信来实现自己的通信协议;
将socket通信整合在tomcat中,利用tomcat来提供http通信,同时实现自己的通信协议。
对于第一种方法,所有的都需要自己来实现,需要自己进行环境的初始化,配置管理,比较麻烦。目前为了方便开发,快速利用web的各种框架,采用的是第二种方法,将socket通信整合在tomcat环境下,随着web的启动,初始化一个socketserver来进行自定义的数据通信。
在web环境下,tomcat整合socket的主要的难处就是如何触发socket服务器的初始化,等待接受来自客户端的连接,且socket服务器的初始化应该只初始化一次。在web启动的时候,toncat会加载context-param -> listener -> filter -> servlet,所以就可以在这些类中来初始化socket服务来进行通信。于是就新建一个SocketServlet并在
public void init(ServletConfig config) throws ServletException
方法中初始化一个ECHO Server的SocketServer来进行通信
// 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中配置:
socketdemo
SocketServlet
1
socketdemo
/demo
但是在启动时候却因为SocketServer一直在运行,Init方法运行不能返回,从而ServletSocket不能运行结束,tomcat最后会因为启动失败而退出。
因而,现在为了解决这个问题,于是就将SocketServer封装在一个线程中
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进行访问: