📄 controlsocket.java
字号:
/* -*- c-basic-offset: 4 -*- * ControlSocket.java -- class for manipulating ControlSockets * Douglas S. J. De Couto, Eddie Kohler * * Copyright (c) 2000 Massachusetts Institute of Technology. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */import java.net.*;import java.io.*;import java.util.Vector;/** * Manage a user-level click Router via its TCP ControlSocket. * * @author Douglas S. J. De Couto, Eddie Kohler */public class ControlSocket { private InetAddress _host; private int _port; private Socket _sock; private BufferedReader _in; private BufferedWriter _out; private int _protocolMinorVersion; private static final int CODE_OK = 200; private static final int CODE_OK_WARN = 220; private static final int CODE_SYNTAX_ERR = 500; private static final int CODE_UNIMPLEMENTED = 501; private static final int CODE_NO_ELEMENT = 510; private static final int CODE_NO_HANDLER = 511; private static final int CODE_HANDLER_ERR = 520; private static final int CODE_PERMISSION = 530; private static final int CODE_NO_ROUTER = 540; public static final int PROTOCOL_MAJOR_VERSION = 1; public static final int PROTOCOL_MINOR_VERSION = 0; /* XXX not sure timeout is a good idea; if we do timeout, we should reset the connection (close and re-open) to get rid of all old data... */ public static final int _sock_timeout = 0; // 1500; // msecs /** * Constructs a new ControlSocket. * * @param host Machine that the user-level click is running on. * @param port Port the Click ControlSocket is listening on. * @exception IOException If there was a problem setting up the * socket and streams, or if the ControlSocket version is wrong, or * if the ControlSocket returned a bad response. * @see java.net.InetAddress */ public ControlSocket(InetAddress host, int port) throws IOException { _host = host; _port = port; /* * setup connection to the node's click ControlSocket */ _sock = new Socket(_host, _port); _sock.setSoTimeout(_sock_timeout); InputStream is = _sock.getInputStream(); OutputStream os = _sock.getOutputStream(); _in = new BufferedReader(new InputStreamReader(is)); _out = new BufferedWriter(new OutputStreamWriter(os)); /* * check version */ try { String banner = _in.readLine(); if (banner == null) throw new IOException("ControlSocket stream closed unexpectedly"); int slash = banner.indexOf('/'); int dot = (slash >= 0 ? banner.indexOf('.', slash + 1) : -1); if (slash < 0 || dot < 0) { _sock.close(); throw new IOException("Unexpected greeting from ControlSocket"); } int majorVersion = Integer.parseInt(banner.substring(slash + 1, dot)); int minorVersion = Integer.parseInt(banner.substring(dot + 1)); if (majorVersion != PROTOCOL_MAJOR_VERSION || minorVersion < PROTOCOL_MINOR_VERSION) { _sock.close(); throw new IOException("Wrong ControlSocket version"); } _protocolMinorVersion = minorVersion; } catch (InterruptedIOException e) { // read timed out throw e; } catch (NumberFormatException e) { throw new IOException("Unexpected greeting from ControlSocket"); } } /** * Returns a String describing the socket's destination address and port. * * @return Socket description. */ public String socketName() { return _sock.getInetAddress().toString() + ":" + _sock.getPort(); } /** * Returns the same String as socketName * * @return Socket description * @see #socketName */ public String toString() { return _host + ":" + _port; } /** * Gets a String containing the router's configuration. * * @return Router configuration. * @exception NoSuchHandlerException If there is no configuration read handler. * @exception HandlerErrorException If the handler returned an error. * @exception PermissionDeniedException If the router would not let us access the handler. * @exception IOException If there was some other error accessing * the handler (e.g., there was a stream or socket error, the * ControlSocket returned an unknwon unknown error code, or the * response could otherwise not be understood). * @see #getRouterFlatConfig * @see #getConfigElementNames */ public String getRouterConfig() throws ClickException, IOException { return readString(null, "config"); } /** * Gets a String containing the router's flattened configuration. * * @return Flattened router configuration. * @exception NoSuchHandlerException If there is no flattened configuration read handler. * @exception HandlerErrorException If the handler returned an error. * @exception PermissionDeniedException If the router would not let us access the handler. * @exception IOException If there was some other error accessing * the handler (e.g., there was a stream or socket error, the * ControlSocket returned an unknwon unknown error code, or the * response could otherwise not be understood). * @see #getRouterConfig * @see #getConfigElementNames */ public String getRouterFlatConfig() throws ClickException, IOException { return readString(null, "flatconfig"); } /** * Gets a String containing the router's version. * * @return Version string. * @exception NoSuchHandlerException If there is no version read handler. * @exception HandlerErrorException If the handler returned an error. * @exception PermissionDeniedException If the router would not let us access the handler. * @exception IOException If there was some other error accessing * the handler (e.g., there was a stream or socket error, the * ControlSocket returned an unknwon unknown error code, or the * response could otherwise not be understood). * @see java.lang.String */ public String getRouterVersion() throws ClickException, IOException { return readString(null, "version").trim(); } /** * Gets the names of elements in the current router configuration. * * @return Vector of Strings of the element names. * @exception NoSuchHandlerException If there is no element list read handler. * @exception HandlerErrorException If the handler returned an error. * @exception PermissionDeniedException If the router would not let us access the handler. * @exception IOException If there was some other error accessing * the handler (e.g., there was a stream or socket error, the * ControlSocket returned an unknwon unknown error code, or the * response could otherwise not be understood). * @see #getElementHandlers * @see #getRouterConfig * @see #getRouterFlatConfig */ public Vector getConfigElementNames() throws ClickException, IOException { char[] buf = read(null, "list"); // how many elements? int i; for (i = 0; i < buf.length && buf[i] != '\n'; i++) ; // do it int numElements = 0; try { numElements = Integer.parseInt(new String(buf, 0, i)); } catch (NumberFormatException ex) { throw new ClickException.HandlerFormatException("element list"); } Vector v = StringUtils.split(buf, i + 1, '\n'); if (v.size() != numElements) throw new ClickException.HandlerFormatException("element list"); return v; } /** * Gets the names of element types that the router knows about. * * @return Vector of Strings of the element names. * @exception NoSuchHandlerException If there is no element list read handler. * @exception HandlerErrorException If the handler returned an error. * @exception PermissionDeniedException If the router would not let us access the handler. * @exception IOException If there was some other error accessing * the handler (e.g., there was a stream or socket error, the * ControlSocket returned an unknwon unknown error code, or the * response could otherwise not be understood). */ public Vector getRouterClasses() throws ClickException, IOException { char[] buf = read(null, "classes"); return StringUtils.split(buf, 0, '\n'); } /** * Gets the names of packages that the router knows about. * * @return Vector of Strings of the package names. * @exception NoSuchHandlerException If there is no element list read handler. * @exception HandlerErrorException If the handler returned an error. * @exception PermissionDeniedException If the router would not let us access the handler. * @exception IOException If there was some other error accessing * the handler (e.g., there was a stream or socket error, the * ControlSocket returned an unknwon unknown error code, or the * response could otherwise not be understood). */ public Vector getRouterPackages() throws ClickException, IOException { char[] buf = read(null, "packages"); return StringUtils.split(buf, 0, '\n'); } /** * Gets the names of the current router configuration requirements. * * @return Vector of Strings of the package names. * @exception NoSuchHandlerException If there is no element list read handler. * @exception HandlerErrorException If the handler returned an error. * @exception PermissionDeniedException If the router would not let us access the handler. * @exception IOException If there was some other error accessing * the handler (e.g., there was a stream or socket error, the * ControlSocket returned an unknwon unknown error code, or the * response could otherwise not be understood). * @see #getRouterConfig * @see #getRouterFlatConfig */ public Vector getConfigRequirements() throws ClickException, IOException { char[] buf = read(null, "requirements"); return StringUtils.split(buf, 0, '\n'); } public static class HandlerInfo { String elementName; String handlerName; boolean canRead; boolean canWrite; HandlerInfo() { this(null, null); } HandlerInfo(String el) { this(el, null); } HandlerInfo(String el, String handler) { elementName = el; handlerName = handler; canRead = canWrite = false; } public String getDescription() { if (elementName == null) return handlerName; else return elementName + "." + handlerName; } public String toString() { return handlerName; } } /** * Gets the information about an element's handlers in the current * router configuration. * * @param el The element name. * @return Vector of HandlerInfo structures. * @exception NoSuchElementException If there is no such element in the current configuration. * @exception HandlerErrorException If the handler returned an error. * @exception PermissionDeniedException If the router would not let us access the handler. * @exception IOException If there was some other error accessing * the handler (e.g., there was a stream or socket error, the * ControlSocket returned an unknwon unknown error code, or the * response could otherwise not be understood). * @see #HandlerInfo * @see #getConfigElementNames * @see #getRouterConfig * @see #getRouterFlatConfig */ public Vector getElementHandlers(String elementName) throws ClickException, IOException { Vector v = new Vector(); Vector vh; try { char[] buf = read(elementName, "handlers"); vh = StringUtils.split(buf, 0, '\n'); } catch (ClickException.NoSuchHandlerException e) { return v; } for (int i = 0; i < vh.size(); i++) { String s = (String) vh.elementAt(i); int j; for (j = 0; j < s.length() && !Character.isWhitespace(s.charAt(j)); j++) ; // find record split if (j == s.length()) throw new ClickException.HandlerFormatException(elementName + ".handlers"); HandlerInfo hi = new HandlerInfo(elementName, s.substring(0, j).trim()); while (j < s.length() && Character.isWhitespace(s.charAt(j))) j++; for ( ; j < s.length(); j++) { char c = s.charAt(j); if (Character.toLowerCase(c) == 'r') hi.canRead = true; else if (Character.toLowerCase(c) == 'w') hi.canWrite = true; else if (Character.isWhitespace(c)) break; } v.addElement(hi); } return v; } /** * Checks whether a read/write handler exists. * * @param elementName The element name. * @param handlerName The handler name. * @param writeHandler True to check write handler, otherwise false. * @return True if handler exists, otherwise false.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -