📄 netadapterhost.java
字号:
/*--------------------------------------------------------------------------- * Copyright (C) 2002 Dallas Semiconductor Corporation, All Rights Reserved. * * 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, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of Dallas Semiconductor * shall not be used except as stated in the Dallas Semiconductor * Branding Policy. *--------------------------------------------------------------------------- */package com.dalsemi.onewire.adapter;import java.io.*;import java.net.*;import java.util.*;import com.dalsemi.onewire.*;import com.dalsemi.onewire.adapter.NetAdapterConstants.*;import com.dalsemi.onewire.utils.*;/** * <P>NetAdapterHost is the host (or server) component for a network-based * DSPortAdapter. It actually wraps the hardware DSPortAdapter and handles * connections from outside sources (NetAdapter) who want to access it.</P> * * <P>NetAdapterHost is designed to be run in a thread, waiting for incoming * connections. You can run this in the same thread as your main program or * you can establish the connections yourself (presumably using some higher * level of security) and then call the <code>handleConnection(Socket)</code> * {@see #handleConnection(Socket)}.</P> * * <P>Once a NetAdapter is connected with the host, a version check is performed * followed by a simple authentication step. The authentication is dependent * upon a secret shared between the NetAdapter and the host. Both will use * a default value, that each will agree with if you don't provide a secret * of your own. To set the secret, add the following line to your * onewire.properties file: * <ul> * <li>NetAdapter.secret="This is my custom secret"</li> * </ul> * Optionally, the secret can be set by calling the <code>setSecret(String)</code> * {@see #setSecret(String)}</P> * * <P>The NetAdapter and NetAdapterHost support multicast broadcasts for * automatic discovery of compatible servers on your LAN. To start the * multicast listener for this NetAdapterHost, call the * <code>createMulticastListener()</code> method * {@see #createMulticastListener()}.</P> * * <P>For information on creating the client component, see the JavaDocs * for the {@link com.dalsemi.onewire.adapter.NetAdapter NetAdapter}. * * @see NetAdapter * * @author SH * @version 1.00, 9 Jan 2002 */public class NetAdapterHost implements Runnable, NetAdapterConstants{ /** random number generator, used to issue challenges to client */ protected static final Random rand = new Random(); /** The adapter this NetAdapter will proxy too */ protected DSPortAdapter adapter = null; /** The server socket for listening for connections */ protected ServerSocket serverSocket = null; /** secret for authentication with the server */ protected byte[] netAdapterSecret = null; /** boolean flags for stopping the host */ protected volatile boolean hostStopped = false, hostRunning = false; /** boolean flag to indicate whether or not the host is single or multi-threaded */ protected boolean singleThreaded = true; /** Map of all Service threads created, only for multi-threaded */ protected Hashtable hashHandlers = null; /** Optional, listens for datagram packets from potential clients */ protected MulticastListener multicastListener = null; /** timeout for socket receive, in seconds */ protected int timeoutInSeconds = 30; /** * <P>Creates an instance of a NetAdapterHost which wraps the provided * adapter. The host listens on the default port as specified by * NetAdapterConstants.</P> * * <P>Note that the secret used for authentication is the value specified * in the onewire.properties file as "NetAdapter.secret=mySecret". * To set the secret to another value, use the * <code>setSecret(String)</code> method.</P> * * @param adapter DSPortAdapter that this NetAdapterHost will proxy * commands to. * * @throws IOException if a network error occurs or the listen socket * cannot be created on the specified port. */ public NetAdapterHost(DSPortAdapter adapter) throws IOException { this(adapter, DEFAULT_PORT, false); } /** * <P>Creates a single-threaded instance of a NetAdapterHost which wraps the * provided adapter. The host listens on the specified port.</P> * * <P>Note that the secret used for authentication is the value specified * in the onewire.properties file as "NetAdapter.secret=mySecret". * To set the secret to another value, use the * <code>setSecret(String)</code> method.</P> * * @param adapter DSPortAdapter that this NetAdapterHost will proxy * commands to. * @param listenPort the TCP/IP port to listen on for incoming connections * * @throws IOException if a network error occurs or the listen socket * cannot be created on the specified port. */ public NetAdapterHost(DSPortAdapter adapter, int listenPort) throws IOException { this(adapter, listenPort, false); } /** * <P>Creates an (optionally multithreaded) instance of a NetAdapterHost * which wraps the provided adapter. The listen port is set to the * default port as defined in NetAdapterConstants.</P> * * <P>Note that the secret used for authentication is the value specified * in the onewire.properties file as "NetAdapter.secret=mySecret". * To set the secret to another value, use the * <code>setSecret(String)</code> method.</P> * * @param adapter DSPortAdapter that this NetAdapterHost will proxy * commands to. * @param multiThread if true, multiple TCP/IP connections are allowed * to interact simulataneously with this adapter. * * @throws IOException if a network error occurs or the listen socket * cannot be created on the specified port. */ public NetAdapterHost(DSPortAdapter adapter, boolean multiThread) throws IOException { this(adapter, DEFAULT_PORT, multiThread); } /** * <P>Creates an (optionally multi-threaded) instance of a NetAdapterHost which * wraps the provided adapter. The host listens on the specified port.</P> * * <P>Note that the secret used for authentication is the value specified * in the onewire.properties file as "NetAdapter.secret=mySecret". * To set the secret to another value, use the * <code>setSecret(String)</code> method.</P> * * @param adapter DSPortAdapter that this NetAdapterHost will proxy * commands to. * @param listenPort the TCP/IP port to listen on for incoming connections * @param multiThread if true, multiple TCP/IP connections are allowed * to interact simulataneously with this adapter. * * @throws IOException if a network error occurs or the listen socket * cannot be created on the specified port. */ public NetAdapterHost(DSPortAdapter adapter, int listenPort, boolean multiThread) throws IOException { //save reference to adapter this.adapter = adapter; // create the server socket this.serverSocket = new ServerSocket(listenPort); // set multithreaded flag this.singleThreaded = !multiThread; if(multiThread) { this.hashHandlers = new Hashtable(); this.timeoutInSeconds = 0; } // get the shared secret String secret = OneWireAccessProvider.getProperty("NetAdapter.secret"); if(secret!=null) netAdapterSecret = secret.getBytes(); else netAdapterSecret = DEFAULT_SECRET.getBytes(); } /** * <P>Creates an instance of a NetAdapterHost which wraps the provided * adapter. The host listens on the default port as specified by * NetAdapterConstants.</P> * * <P>Note that the secret used for authentication is the value specified * in the onewire.properties file as "NetAdapter.secret=mySecret". * To set the secret to another value, use the * <code>setSecret(String)</code> method.</P> * * @param adapter DSPortAdapter that this NetAdapterHost will proxy * commands to. * @param serverSock the ServerSocket for incoming connections * * @throws IOException if a network error occurs or the listen socket * cannot be created on the specified port. */ public NetAdapterHost(DSPortAdapter adapter, ServerSocket serverSock) throws IOException { this(adapter, serverSock, false); } /** * <P>Creates an (optionally multi-threaded) instance of a NetAdapterHost which * wraps the provided adapter. The host listens on the specified port.</P> * * <P>Note that the secret used for authentication is the value specified * in the onewire.properties file as "NetAdapter.secret=mySecret". * To set the secret to another value, use the * <code>setSecret(String)</code> method.</P> * * @param adapter DSPortAdapter that this NetAdapterHost will proxy * commands to. * @param serverSock the ServerSocket for incoming connections * @param multiThread if true, multiple TCP/IP connections are allowed * to interact simulataneously with this adapter. * * @throws IOException if a network error occurs or the listen socket * cannot be created on the specified port. */ public NetAdapterHost(DSPortAdapter adapter, ServerSocket serverSock, boolean multiThread) throws IOException { //save reference to adapter this.adapter = adapter; // create the server socket this.serverSocket = serverSock; // set multithreaded flag this.singleThreaded = !multiThread; if(multiThread) { this.hashHandlers = new Hashtable(); this.timeoutInSeconds = 0; } // get the shared secret String secret = OneWireAccessProvider.getProperty("NetAdapter.secret"); if(secret!=null) netAdapterSecret = secret.getBytes(); else netAdapterSecret = DEFAULT_SECRET.getBytes(); } /** * Sets the secret used for authenticating incoming client connections. * * @param secret The shared secret information used for authenticating * incoming client connections. */ public void setSecret(String secret) { netAdapterSecret = secret.getBytes(); } /** * Creates a Multicast Listener to allow NetAdapter clients to discover * this NetAdapterHost automatically. Uses defaults for Multicast group * and port. */ public void createMulticastListener() throws IOException,UnknownHostException { createMulticastListener(DEFAULT_MULTICAST_PORT); } /** * Creates a Multicast Listener to allow NetAdapter clients to discover * this NetAdapterHost automatically. Uses default for Multicast group. * * @param port The port the Multicast socket will receive packets on */ public void createMulticastListener(int port) throws IOException,UnknownHostException { String group = OneWireAccessProvider.getProperty("NetAdapter.MulticastGroup"); if(group==null) group = DEFAULT_MULTICAST_GROUP; createMulticastListener(port, group); } /** * Creates a Multicast Listener to allow NetAdapter clients to discover * this NetAdapterHost automatically. * * @param port The port the Multicast socket will receive packets on * @param group The group the Multicast socket will join */ public void createMulticastListener(int port, String group) throws IOException,UnknownHostException { if(multicastListener==null) { // 4 bytes for integer versionUID byte[] versionBytes = Convert.toByteArray(versionUID); // this byte array is 5 because length is used to determine different // packet types by client byte[] listenPortBytes = new byte[5]; Convert.toByteArray(serverSocket.getLocalPort(), listenPortBytes, 0, 4); listenPortBytes[4] = (byte)0x0FF; multicastListener = new MulticastListener(port, group, versionBytes, listenPortBytes); (new Thread(multicastListener)).start(); } } /** * Run method for threaded NetAdapterHost. Maintains server socket which * waits for incoming connections. Whenever a connection is received * launches it services the socket or (optionally) launches a new thread * for servicing the socket. */ public void run() { hostRunning = true; while(!hostStopped) { Socket sock = null; try { sock = serverSocket.accept(); handleConnection(sock); } catch(IOException ioe1) { try { if(sock!=null) sock.close(); } catch(IOException ioe2) {;} } } hostRunning = false; } /** * Handles a socket connection. If single-threaded, the connection is * serviced in the current thread. If multi-threaded, a new thread is * created for servicing this connection. */ public void handleConnection(Socket sock) throws IOException { SocketHandler sh = new SocketHandler(sock); if(singleThreaded) { // single-threaded sh.run(); } else { // multi-threaded Thread t = new Thread(sh); t.start(); synchronized(hashHandlers) { hashHandlers.put(t, sh); } } } /** * Stops all threads and kills the server socket. */ public void stopHost() { this.hostStopped = true; try { this.serverSocket.close(); } catch(IOException ioe) {;} // wait for run method to quit, with a timeout of 1 second int i = 0; while(hostRunning && i++<100) try{Thread.sleep(10);}catch(Exception e){;} if(!singleThreaded) { synchronized(hashHandlers) { Enumeration e = hashHandlers.elements(); while(e.hasMoreElements()) ((SocketHandler)e.nextElement()).stopHandler(); } } if(multicastListener!=null) multicastListener.stopListener(); // ensure that there is no exclusive use of the adapter adapter.endExclusive(); } /** * Transmits the versionUID of the current NetAdapter protocol to * the client connection. If it matches the clients versionUID, * the client returns RET_SUCCESS. * * @param conn The connection to send/receive data. * @return <code>true</code> if the versionUID matched. */ private boolean sendVersionUID(Connection conn) throws IOException { // write server version conn.output.writeInt(versionUID); conn.output.flush(); byte retVal = conn.input.readByte(); return (retVal==RET_SUCCESS); } /** * Reads in command from client and calls the appropriate handler function. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -