📄 remoteprintserver.java
字号:
/* * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product that is * described in this document. In particular, and without limitation, these intellectual property rights may * include one or more of the U.S. patents listed at http://www.sun.com/patents and one or more additional patents * or pending patent applications in the U.S. and in other countries. * * U.S. Government Rights - Commercial software. Government users are subject to the Sun Microsystems, Inc. * standard license agreement and applicable provisions of the FAR and its supplements. * * Use is subject to license terms. * * This distribution may include materials developed by third parties. Sun, Sun Microsystems, the Sun logo and * Java are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. * * Copyright (c) 2006 Sun Microsystems, Inc. Tous droits r?serv?s. * * Sun Microsystems, Inc. d?tient les droits de propri?t? intellectuels relatifs ? la technologie incorpor?e dans * le produit qui est d?crit dans ce document. En particulier, et ce sans limitation, ces droits de propri?t? * intellectuelle peuvent inclure un ou plus des brevets am?ricains list?s ? l'adresse http://www.sun.com/patents * et un ou les brevets suppl?mentaires ou les applications de brevet en attente aux Etats - Unis et dans les * autres pays. * * L'utilisation est soumise aux termes du contrat de licence. * * Cette distribution peut comprendre des composants d?velopp?s par des tierces parties. * Sun, Sun Microsystems, le logo Sun et Java sont des marques de fabrique ou des marques d?pos?es de Sun * Microsystems, Inc. aux Etats-Unis et dans d'autres pays. */package org.sunspotworld.remoteprinting; import java.util.*;import java.io.*;import javax.microedition.io.Datagram;import javax.microedition.io.DatagramConnection;import javax.microedition.io.Connector;import com.sun.spot.io.j2me.radiogram.*;import com.sun.spot.util.IEEEAddress; /** * RemotePrintServer is used to create a thread to listen for remote printing requests * that are broadcast with a Radiogram packet from a remote SPOT. When a request is received * a RemotePrintHandler thead is spawned to wait for remote printing and echo the characters * to a PrintStream where they will be displayed. * <p> * A factory method to create the PrintStream can be specified using setRemotePrintStreamFactory. * If no factory method is set, then System.out will be used to display the remote printing. * <p> * To have a SPOT act as a remote print server all that is needed is to have a SPOT application * call: * <p> * <code>RemotePrintServer.enable(); </code> * <p> * That will start up a server thread to listen and handle remote printing requests. * * @author Ron Goldman * @see RemotePrinting */public class RemotePrintServer implements Runnable { /** Default port to use for remote printing (=119) */ public final static byte DEFAULT_REMOTE_PRINT_PORT = 119; // would prefer 911 but it's too big /** Packet type for a remote printing request (broadcast to potential servers) */ public final static byte REMOTE_PRINT_REQ = 31; // could just use 1 & 2.... /** Packet type sent by a remote print server in answer to a remote printing request */ public final static byte REMOTE_PRINT_ACK = 75; /** Packet type sent when a remote print server starts up or stops */ public final static byte REMOTE_PRINT_INIT = 62; private final static int BUFFER_SIZE = 256; private static byte remotePrintPort = DEFAULT_REMOTE_PRINT_PORT; private static byte remotePrintServerPort = remotePrintPort; private static Hashtable remotePrintThreads = new Hashtable(); private static RemotePrintServer rsrv = new RemotePrintServer(); private static RemotePrintStreamFactory factory = null; private DatagramConnection txConn = null; private RadiogramConnection rcvConn = null; private boolean running = false; private Thread th; /** * Turn on the remote print server and start listening for remote printing requests. */ public static void enable () { rsrv.enableThread(); } /** * Disconnect any current connections and turn off the remote print server. */ public static void disable () { rsrv.disableThread(); } /** * Return the port number being used for remote printing. * * @return the port number (0-127) */ public static byte getPort() { return remotePrintPort; } /** * Set the port to use for remote printing. * Note will not take effect until the next time that remote printing is enabled. * * @param port the port number (0-127) */ public static void setPort (int port) { if (0 <= port && port <= 127) { remotePrintPort = (byte)port; } else { throw new IllegalArgumentException("Port number out of valid range (0-127)"); } } /** * Return the current number of remote printing connections. * * @return the number of connections in use */ public static int getNumberConnections () { int num = 0; for (Enumeration e = remotePrintThreads.elements() ; e.hasMoreElements() ;) { e.nextElement(); num++; } return num; } /** * Set a RemotePrintStreamFactory callback to create a PrintStream to display the remote printing stream. * * @param factory the class implementing the callback */ public static void setRemotePrintStreamFactory (RemotePrintStreamFactory factory) { RemotePrintServer.factory = factory; } /** Creates a new instance of RemotePrintServer */ private RemotePrintServer() { } /** * Turn on the remote print server and start listening for remote printing requests. */ private void enableThread () { if (!running) { running = true; th = new Thread(this); th.start(); } } /** * Disconnect any current connections and turn off the remote print server. */ private void disableThread () { running = false; for (Enumeration e = remotePrintThreads.elements() ; e.hasMoreElements() ;) { RemotePrintHandler rph = (RemotePrintHandler)e.nextElement(); rph.quit(); Thread.yield(); } remotePrintThreads.clear(); try { if (txConn != null) { Datagram xdg = txConn.newDatagram(txConn.getMaximumLength()); xdg.reset(); xdg.writeByte(REMOTE_PRINT_INIT); // packet type sendPacket(xdg); // announce we are stopping txConn.close(); txConn = null; } if (rcvConn != null) { rcvConn.close(); rcvConn = null; } } catch (IOException ex) { /* ignore */ } try { Thread.currentThread().sleep(1000); // give running thread time to shut down } catch (InterruptedException ex) { /* ignore */ } } /** * Send off a packet via broadcast. * * @param xdg the Radiogram packet to send */ private void sendPacket (Datagram xdg) { for (int retry = 0; retry < 5; retry++) { try { txConn.send(xdg); // broadcast remote print request break; } catch (IOException ex) { // just retry } } } /** * Internal loop to receive remote print requests and to open a stream for them. * Do not call directly. Call RemotePrintServer.enable() instead. */ public void run () { try { txConn = (DatagramConnection)Connector.open("radiogram://broadcast:" + remotePrintPort); int max = txConn.getMaximumLength(); Datagram xdg = txConn.newDatagram(max); rcvConn = (RadiogramConnection)Connector.open("radiogram://:" + remotePrintPort); rcvConn.setTimeout(-1); // do not want any timeouts Datagram dg = rcvConn.newDatagram(max); remotePrintServerPort = remotePrintPort; xdg.reset(); xdg.writeByte(REMOTE_PRINT_INIT); // packet type sendPacket(xdg); // announce we just started up while (running && th == Thread.currentThread()) { dg.reset(); rcvConn.receive(dg); // wait until we receive a request if (!running || th != Thread.currentThread()) { return; } else if (dg.readByte() == REMOTE_PRINT_REQ) { // type of packet String addr = dg.getAddress(); IEEEAddress ieeeAddr = new IEEEAddress(addr); long macAddress = ieeeAddr.asLong(); xdg.reset(); xdg.writeByte(REMOTE_PRINT_ACK); // packet type xdg.writeLong(macAddress); // requestor's ID xdg.writeByte(remotePrintServerPort); sendPacket(xdg); String key = Long.toString(macAddress) + ":" + Integer.toString(remotePrintServerPort); RemotePrintHandler rph = (RemotePrintHandler)remotePrintThreads.get(key); if (rph == null || !rph.isRunning()) { // do not have a running handler for this address PrintStream out = (factory == null) ? System.out : factory.makePrintStream("[" + ieeeAddr.asDottedHex() + "]"); rph = new RemotePrintHandler(Long.toString(macAddress), remotePrintServerPort, out); // rph = new RemotePrintHandler(macAddress, remotePrintServerPort, out); remotePrintThreads.put(key, rph); rph.start(); Thread.yield(); } else if (factory != null) { // have already handled this address, so just show it factory.showPrintStream("[" + ieeeAddr.asDottedHex() + "]"); } } } } catch (InterruptedIOException iex) { /* ignore */ } catch (Exception ex) { System.out.println("Error reading remote printing request: " + ex.toString()); } finally { if (running && th == Thread.currentThread()) { try { if (txConn != null) { txConn.close(); txConn = null; } if (rcvConn != null) { rcvConn.close(); rcvConn = null; } } catch (IOException ex) { /* ignore */ } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -