📄 server.java
字号:
package net.sf.dz.view.tcp.server;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import javax.net.ssl.SSLException;import org.freehold.jukebox.conf.Configuration;import org.freehold.jukebox.logger.LogChannel;import org.freehold.jukebox.logger.LogAware;import org.freehold.jukebox.logger.Logger;import org.freehold.jukebox.service.ActiveService;import org.freehold.jukebox.service.Messenger;import net.sf.dz.Model;import net.sf.dz.util.SSLContextFactory;import net.sf.dz.view.View;/** * The TCP server view. * * Presents the {@link net.sf.dz.Model model} to the remote. * * @author Copyright © <a href="mailto:vt@freehold.crocodile.org">Vadim Tkachenko</a> 2001-2002 * @version $Id: Server.java,v 1.7 2004/06/28 20:35:50 vtt Exp $ */public class Server extends ActiveService implements View { public static final LogChannel CH_VS = new LogChannel("View/TCP"); /** * The model to reflect on. */ private Model model; /** * The reflection model. */ private ModelServerProxy modelProxy; /** * The listener socket. */ private ServerSocket serverSocket; /** * The bind address. */ private InetAddress bindAddress; /** * The port to listen to. */ private int port; /** * Is the connection requested to be secure. */ private boolean secure; /** * Password for the key store. * * VT: Don't tell me it's insecure, just fix the implementation to be * more secure, all right? */ private String password; public void attach(Model model) { if ( model == null ) { throw new IllegalArgumentException("Model can't be null"); } if ( this.model != null ) { throw new IllegalStateException("Already attached to the model"); } this.model = model; } protected void configure() throws Throwable { if ( model == null ) { throw new IllegalStateException("Model must be attached first"); } Configuration cf = getConfiguration(); String cfroot = getConfigurationRoot(); bindAddress = InetAddress.getByName(cf.getString(cfroot + ".tcp.host", "localhost")); // VT: FIXME: Has to be set to 5004 later port = cf.getInteger(cfroot + ".tcp.port", 5014); secure = cf.getBoolean(cfroot + ".tcp.secure"); if ( secure ) { password = cf.getString(cfroot + ".tcp.password"); } } protected void startup() throws Throwable { // Check if we're configured getConfiguration(); modelProxy = new ModelServerProxy(getLogger(), model); if ( secure ) { complain(LOG_NOTICE, CH_VS, "Secure connection requested"); // VT: FIXME: It may make sense to be more flexible in // creating the SSL context try { serverSocket = SSLContextFactory.createContext(password).getServerSocketFactory().createServerSocket(port, 256, bindAddress); } catch ( SSLException sslex ) { complain(LOG_WARNING, CH_VS, "Can't establish a secure listener on " + bindAddress + ":" + port, sslex ); complain(LOG_WARNING, CH_VS, "Reverting to insecure connection"); } } if ( serverSocket == null ) { serverSocket = new ServerSocket(port, 256, bindAddress); } complain(LOG_INFO, CH_VS, "Listening on " + bindAddress + ":" + port); } protected void execute() throws Throwable { while ( isEnabled() ) { Socket s = serverSocket.accept(); // VT: FIXME: check the access list, instantiate the security // wrapper, if any (new ClientHandler(getLogger(), s)).start(); } } protected void shutdown(Throwable cause) throws Throwable { } protected class ClientHandler extends Messenger { private LogChannel CH_CH; private Socket s; public ClientHandler(Logger logger, Socket s) { super(logger); this.s = s; CH_CH = new LogChannel(CH_VS, s.getRemoteSocketAddress().toString()); } /** * Handle the incoming connection. * * VT: NOTE: Have to be careful here - the messenger's problems are * swallowed if there are no listeners to the ACT. * * @return The result - will be discarded. */ public Object execute() throws Throwable { BufferedReader br = null; PrintWriter pw = null; try { complain(LOG_INFO, CH_CH, "client arrived"); br = new BufferedReader(new InputStreamReader(s.getInputStream())); pw = new PrintWriter(s.getOutputStream()); // Deliver the model's introspection to the client modelProxy.renderReflection(pw); // Dump the current state modelProxy.dumpState(pw); // Add this object as a listener so we can convey the // messages to the client modelProxy.listen(pw); while ( true ) { String line = br.readLine(); if ( line == null ) { complain(LOG_INFO, CH_CH, "EOF"); return null; } complain(LOG_DEBUG, CH_CH, "Command received: '" + line + "'"); try { modelProxy.parse(line); } catch ( Throwable t ) { // We applied our best efforts to handle the input, so // there's a problem with the line being parsed, or the // implementation. Let's see what caused it: complain(LOG_WARNING, CH_CH, "Parse failure, command '" + line + "', cause:", t); } } } catch ( Throwable t ) { complain(LOG_WARNING, CH_CH, "Client handler terminated with exception:", t); } finally { // VT: NOTE: Have to handle all the unfinished business // right here, otherwise it will just disappear - this is // how Messenger works modelProxy.ignore(pw); // Don't let the socket close (which will probably fail) // mask the real problem, if any try { s.close(); } catch ( IOException ioex ) { // Ignore it, there's nothing we can do } } return null; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -