📄 simplesslserver.java
字号:
import javax.net.ssl.*;import java.security.cert.*;import java.io.*;/** * 该类是一个简单的服务器程序.它的功能是接受SSL连接请求,然后再标准显示设备上 * 显示通过SSL套接字接收到的数据流.该服务器缺省运行在49152端口上,它需要进行 * 客户端验证.通过输入Ctrl-C可以终止该程序. */public class SimpleSSLServer extends Thread{ private static final int DEFAULT_PORT=49152; private SSLServerSocketFactory serverSocketFactory; private int port; /** * 该方法首先处理命令行参数,然后开始监听连接请求. */ public static void main(String args[]) { int port=DEFAULT_PORT; // 解释参数 boolean parseFailed=false; try { for (int i=0; i<args.length; i++) { String arg=args[i].trim().toUpperCase(); // 目前只支持"-port"参数 if (arg.equals("-PORT")) port=Integer.parseInt(args[++i]); else parseFailed=true; } } catch(Exception e) { // 命令行参数解释错误,显示提示信息. parseFailed=true; } if (parseFailed) { displayUsage(); } else { // 命令行参数解释成功. // 利用缺省的SSLServerSocketFactory对象创建一个SimpleSSLServer对象, // 然后启动该SimpleSSLServer对象. SSLServerSocketFactory ssf= (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); SimpleSSLServer server=new SimpleSSLServer(ssf, port); server.start(); } } /** 显示命令行用法 */ private static void displayUsage() { System.out.println("Options:"); System.out.println("\t-port\tport of server (default "+DEFAULT_PORT+")"); } /** *在指定端口上创建一个SimpleSSLServer对象. */ public SimpleSSLServer(SSLServerSocketFactory ssf, int port) { serverSocketFactory=ssf; this.port=port; } /** * SimpleSSLServer对象运行在一个单独的线程中.run()方法中实现了一个死循环, * 服务器在该循环中监听客户端的连接申请.用户按下Ctrl-C可以退出该循环. */ public void run() { System.out.println("SimpleSSLServer running on port "+port); try { // 首先创建一个安全套接字对象 SSLServerSocket serverSocket= (SSLServerSocket)serverSocketFactory.createServerSocket(port); serverSocket.setNeedClientAuth(true); // 每个连接都有一个ID号,该ID号从1开始 int id=1; // 监听连接请求.对于每个请求打开一个新的线程. while(true) { String ident=String.valueOf(id++); // 监听连接请求. SSLSocket socket=(SSLSocket)serverSocket.accept(); // 通过使用HandshakeCompletedListener对象,程序可以进行授权验证. HandshakeCompletedListener hcl=new SimpleHandshakeListener(ident); socket.addHandshakeCompletedListener(hcl); InputStream in=socket.getInputStream(); new InputDisplayer(ident, in); } } catch(IOException ioe) { System.out.println("SimpleSSLServer failed with following exception:"); System.out.println(ioe); ioe.printStackTrace(); } } /** * HandshakeCompletedListener类显示客户端传来的授权信息. */ class SimpleHandshakeListener implements HandshakeCompletedListener { String ident; /** * 构造函数. */ public SimpleHandshakeListener(String ident) { this.ident=ident; } /** 当SSL握手过程完成后该方法被激活. */ public void handshakeCompleted(HandshakeCompletedEvent event) { // 显示授权信息. try { X509Certificate cert=(X509Certificate)event.getPeerCertificates()[0]; String peer=cert.getSubjectDN().getName(); System.out.println(ident+": Request from "+peer); } catch (SSLPeerUnverifiedException pue) { System.out.println(ident+": Peer unverified"); } } } /** * 该类将套接字接收到的数据流传送到标准输出. */ class InputDisplayer extends Thread { BufferedReader reader; String ident; /** * 构造函数. */ InputDisplayer(String ident, InputStream is) { this.ident=ident; log("New connection request"); // 利用InputStream对象创建一个InputStreamReader对象.该InputStreamReader // 对象将数据流中的字节转化为字符,然后利用一个BufferedReader对象将数据流 // 按行分解. try { reader=new BufferedReader(new InputStreamReader(is, "UTF-8")); } catch (UnsupportedEncodingException uee) { log("Warning: JVM cannot support UTF-8. Using default instead"); reader=new BufferedReader(new InputStreamReader(is)); } setDaemon(true); start(); } /** * 将数据按行输出到屏幕. */ public void run() { boolean done=false; try { while (!done) { String line=reader.readLine(); if (line!=null) display(line); else done=true; } log("Client disconnected"); } catch(IOException ioe) { // IO错误,记录错误并退出. log(ioe.toString()); log("Closing connection."); } try { reader.close(); } catch(IOException ioe) {} } /** * 该方法进行日志处理. */ private void log(String text) { System.out.println(ident+": "+text); } private void display(String text) { System.out.println(ident+"> "+text); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -