⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serverlookup.java

📁 Bluetooth chat Server and Client in j2me
💻 JAVA
字号:
/* The Bluetooth Library for client-server communication Copyright (C) 2006 Martin Vysny This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. */package net.sf.btw.btlib;import java.util.Enumeration;import java.util.Vector;import javax.bluetooth.BluetoothStateException;import javax.bluetooth.DeviceClass;import javax.bluetooth.DiscoveryAgent;import javax.bluetooth.DiscoveryListener;import javax.bluetooth.RemoteDevice;import javax.bluetooth.ServiceRecord;import javax.bluetooth.UUID;import net.sf.btw.tools.ArrayUtils;import net.sf.btw.tools.Logger;/** * Looks for available servers. *  * @author Martin Vysny */public final class ServerLookup extends Thread implements DiscoveryListener {	/**	 * If <code>true</code> then the thread should terminate ASAP.	 */	private volatile boolean interrupted = false;	/**	 * Constructs new instance of thread. You have to call	 * {@link #searchForServers()} to initiate the search.	 * 	 * @param serverId	 *            ID of the server to search for.	 * @param listener	 *            the listener. Must not be <code>null</code>.	 */	public ServerLookup(final UUID serverId, final ILookupListener listener) {		super();		if (listener == null)			throw new IllegalArgumentException("listener must not be null"); //$NON-NLS-1$		this.listener = listener;		this.serverId = serverId;		discoveryAgent = Peer.getDevice().getDiscoveryAgent();	}	private final static int STATE_NOT_STARTED = 0;	private final static int STATE_INQUIRY = 1;	private final static int STATE_SERVICE_SEARCH = 2;	private final static int STATE_TERMINATED = 3;	/**	 * The state of the thread. One of <code>STATE_</code> constants.	 */	private volatile int state = STATE_NOT_STARTED;	/*	 * (non-Javadoc)	 * 	 * @see java.lang.Thread#run()	 */	public void run() {		// this ensures that no other service search/inquiry is in progress.		synchronized (ServerInfo.DISCOVERY_LOCK) {			clientSearchForServers();		}	}	/**	 * The listener instance.	 */	private final ILookupListener listener;	/**	 * Server UUID.	 */	public final UUID serverId;	private final DiscoveryAgent discoveryAgent;	/**	 * Current active service transaction ID.	 */	private int serviceTransactionID = -1;	/**	 * <p>	 * Searches for available servers. The method will not block. It will	 * gradually fill the {@link #servers} list. The method will do nothing if a	 * search is already in progress. This method may be called only once - if a	 * second scan is required then a new instance must be made.	 * </p>	 * <p>	 * If the {@link ServerInfo#connectToServer(UUID)} is in progress the lookup	 * will wait until the function finishes.	 * </p>	 */	public void searchForServers() {		if (isSearching())			return;		start();	}	/**	 * Checks if the server search is in progress.	 * 	 * @return <code>true</code> if the search did not end yet,	 *         <code>false</code> otherwise.	 */	public boolean isSearching() {		int s = state;		return (s == STATE_INQUIRY) || (s == STATE_SERVICE_SEARCH);	}	/**	 * Servers found. Contains instances of {@link ServerInfo}.	 */	public final Vector servers = new Vector();	/**	 * Executes the search.	 */	private void clientSearchForServers() {		remoteDevices.removeAllElements();		servers.removeAllElements();		try {			discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);			state = STATE_INQUIRY;			synchronized (remoteDevices) {				remoteDevices.wait();			}			for (final Enumeration e = remoteDevices.elements(); e					.hasMoreElements();) {				try {					final RemoteDevice remoteDevice = (RemoteDevice) e							.nextElement();					serviceTransactionID = discoveryAgent.searchServices(null,							new UUID[] { serverId }, remoteDevice, this);					state = STATE_SERVICE_SEARCH;					synchronized (remoteDevices) {						remoteDevices.wait();					}				} catch (Exception ex) {					Logger							.error(									"ServerLookup.clientSearchForServers():serviceSearch", //$NON-NLS-1$									ex);					if (!interrupted)						listener.serverScanError(ex);				}			}			listener.serverScanFinished(servers, !interrupted);		} catch (InterruptedException e) {			// do nothing, the thread is interrupted and should end.			listener.serverScanFinished(servers, false);		} catch (Exception ex) {			Logger.error("ServerLookup.searchForServers()", ex); //$NON-NLS-1$			listener.serverScanError(ex);		}		state = STATE_TERMINATED;	}	/**	 * {@link #searchForServers()} blocks on this object. Contains list of	 * {@link RemoteDevice}.	 */	private final Vector remoteDevices = new Vector();	/**	 * Not intended to be called by clients.	 */	public void deviceDiscovered(RemoteDevice arg0, DeviceClass arg1) {		remoteDevices.addElement(arg0);		if (Logger.CURRENT_LEVEL < Logger.LEVEL_DEBUG)			return;		Logger.debug("ServerLookup.deviceDiscovered(): " //$NON-NLS-1$				+ Peer.getDeviceName(arg0, true), null);	}	/**	 * Not intended to be called by clients.	 */	public void inquiryCompleted(int discType) {		final boolean forcefullyTerminated = (discType == INQUIRY_TERMINATED)				&& interrupted;		final boolean error = (discType != INQUIRY_COMPLETED)				&& !forcefullyTerminated;		Logger				.log(error ? Logger.LEVEL_ERROR : Logger.LEVEL_INFO,						"ServerLookup.inquiryCompleted(): " //$NON-NLS-1$								+ getInqErrorCode(discType), null);		if (error) {			listener.serverScanError(new BluetoothStateException(					"Inquiry error - is bluetooth enabled?")); //$NON-NLS-1$		}		synchronized (remoteDevices) {			remoteDevices.notify();		}	}	/**	 * Returns displayable value of given inquiry error code.	 * 	 * @param discType	 *            the inquiry error code issued by	 *            {@link DiscoveryListener#inquiryCompleted(int)}.	 * @return displayable error code, never <code>null</code>.	 */	public static String getInqErrorCode(final int discType) {		switch (discType) {		case INQUIRY_COMPLETED:			return "ICompleted"; //$NON-NLS-1$		case INQUIRY_ERROR:			return "IError"; //$NON-NLS-1$		case INQUIRY_TERMINATED:			return "ITerminated"; //$NON-NLS-1$		default:			return "IUnknown(" + discType + ")"; //$NON-NLS-1$ //$NON-NLS-2$		}	}	/**	 * Not intended to be called by clients.	 */	public void servicesDiscovered(int arg0, ServiceRecord[] arg1) {		if ((arg1 == null) || arg1.length == 0) {			Logger.debug("Discovered 0 services, ignoring", null); //$NON-NLS-1$			return;		}		final ServerInfo si = new ServerInfo(arg1[0].getHostDevice());		// check if this server has been found already		final int serverIndex = ArrayUtils.indexOf(servers, si);		if (serverIndex >= 0) {			// discard newly created server info.			Logger.debug("ServerLookup.servicesDiscovered(): Found " //$NON-NLS-1$					+ arg1.length + " service(s) on existing server " + si, //$NON-NLS-1$					null);			return;		}		// okay, service seems unique. register it		Logger.debug("ServerLookup.servicesDiscovered(): Found " + arg1.length //$NON-NLS-1$				+ " service(s) on new server" + si, null); //$NON-NLS-1$		servers.addElement(si);		if (!interrupted)			listener.serverFound(si);	}	/**	 * Not intended to be called by clients.	 */	public void serviceSearchCompleted(int arg0, int respCode) {		final boolean forcefullyTerminated = (respCode == SERVICE_SEARCH_TERMINATED)				&& interrupted;		final boolean error = (respCode != SERVICE_SEARCH_COMPLETED)				&& (respCode != SERVICE_SEARCH_NO_RECORDS)				&& !forcefullyTerminated;		Logger.log(error ? Logger.LEVEL_ERROR : Logger.LEVEL_INFO,				"ServerLookup.serviceSearchCompleted(): " //$NON-NLS-1$						+ getServiceErrorCode(respCode), null);		synchronized (remoteDevices) {			remoteDevices.notify();		}	}	/**	 * Returns displayable value of given service search error code.	 * 	 * @param respCode	 *            the service search error code issued by	 *            {@link DiscoveryListener#serviceSearchCompleted(int, int)}.	 * @return displayable error code, never <code>null</code>.	 */	public static String getServiceErrorCode(final int respCode) {		switch (respCode) {		case SERVICE_SEARCH_COMPLETED:			return "SSCompleted"; //$NON-NLS-1$		case SERVICE_SEARCH_DEVICE_NOT_REACHABLE:			return "SSDeviceNotReachable"; //$NON-NLS-1$		case SERVICE_SEARCH_ERROR:			return "SSError"; //$NON-NLS-1$		case SERVICE_SEARCH_NO_RECORDS:			return "SSNoRecords"; //$NON-NLS-1$		case SERVICE_SEARCH_TERMINATED:			return "SSTerminated"; //$NON-NLS-1$		default:			return "SSUnknown(" + respCode + ")"; //$NON-NLS-1$ //$NON-NLS-2$		}	}	/**	 * Stops the server search. No further server discovery events will be	 * invoked on the listener, except the	 * {@link ILookupListener#serverScanFinished(Vector, boolean)}.	 */	public void interrupt() {		interrupted = true;		// super.interrupt();		switch (state) {		case STATE_INQUIRY:			discoveryAgent.cancelInquiry(this);			break;		case STATE_SERVICE_SEARCH:			discoveryAgent.cancelServiceSearch(serviceTransactionID);			break;		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -