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

📄 serverinfo.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.io.ByteArrayInputStream;import java.io.DataInputStream;import java.io.IOException;import javax.bluetooth.DeviceClass;import javax.bluetooth.DiscoveryAgent;import javax.bluetooth.DiscoveryListener;import javax.bluetooth.L2CAPConnection;import javax.bluetooth.RemoteDevice;import javax.bluetooth.ServiceRecord;import javax.bluetooth.UUID;import javax.microedition.io.Connector;import net.sf.btw.tools.Logger;import net.sf.btw.tools.StreamUtils;/** * A simple bean holding server info. *  * @author Martin Vysny */public final class ServerInfo implements DiscoveryListener {	/**	 * Creates instance of the info.	 * 	 * @param device	 *            the device	 */	public ServerInfo(final RemoteDevice device) {		super();		this.device = device;		bluetoothAddress = device.getBluetoothAddress();		displayableName = Peer.getDeviceName(device, false);	}	/**	 * The remote device reference.	 */	public final RemoteDevice device;	/**	 * Bluetooth unique address.	 */	public final String bluetoothAddress;	/**	 * Displayable name of the server.	 */	public String displayableName;	/*	 * (non-Javadoc)	 * 	 * @see java.lang.Object#toString()	 */	public String toString() {		return displayableName;	}	/*	 * (non-Javadoc)	 * 	 * @see java.lang.Object#equals(java.lang.Object)	 */	public boolean equals(Object obj) {		if (obj == this)			return true;		if (!(obj instanceof ServerInfo))			return false;		final ServerInfo other = (ServerInfo) obj;		return bluetoothAddress.equals(other.bluetoothAddress);	}	/*	 * (non-Javadoc)	 * 	 * @see java.lang.Object#hashCode()	 */	public int hashCode() {		return bluetoothAddress.hashCode();	}	/**	 * Not intended to be called by clients.	 */	public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {		// not used	}	/**	 * Not intended to be called by clients.	 */	public void inquiryCompleted(int discType) {		// not used	}	/**	 * Not intended to be called by clients.	 */	public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {		if ((servRecord == null) || servRecord.length == 0) {			Logger.debug("ServerInfo.servicesDiscovered(): 0 services", null); //$NON-NLS-1$			return;		}		// try to obtain a connection		clientId = tryToConnect(servRecord);		if (connection != null) {			// We got a connection. interrupt!			discoveryAgent.cancelServiceSearch(serviceTransactionID);			synchronized (lock) {				lock.notify();			}		}	}	private static final DiscoveryAgent discoveryAgent = Peer.getDevice()			.getDiscoveryAgent();	/**	 * Not intended to be called by clients.	 * 	 * @see javax.bluetooth.DiscoveryListener#serviceSearchCompleted(int, int)	 */	public void serviceSearchCompleted(int transID, int respCode) {		final boolean forcefullyTerminated = (respCode == SERVICE_SEARCH_TERMINATED)				&& (connection != null);		final boolean error = (respCode != SERVICE_SEARCH_COMPLETED)				&& (respCode != SERVICE_SEARCH_NO_RECORDS)				&& !forcefullyTerminated;		Logger.log(error ? Logger.LEVEL_ERROR : Logger.LEVEL_INFO,				"ServerInfo.serviceSearchCompleted(): " //$NON-NLS-1$						+ ServerLookup.getServiceErrorCode(respCode), null);		synchronized (lock) {			lock.notify();		}	}	/**	 * Thread must lock onto this object prior inquiry/service search.	 */	static final Object DISCOVERY_LOCK = new Object();	/**	 * <p>	 * Tries to obtain a connection to this server. The function blocks until a	 * connection is made or an exception is thrown. This function synchronizes	 * to its class instance hence only one VM thread may enter this method on a	 * single instance of the object.	 * </p>	 * <p>	 * Warning: This function uses service discovery: it should not be called	 * while another discovery is in progress as some phones support no	 * concurrent service discovery/inquiry. If a {@link ServerLookup} is in	 * progress the function will block until the lookup is finished. You should	 * NOT call this function from {@link ILookupListener} methods - the	 * function will not deadlock but the search may fail.	 * </p>	 * 	 * @param serverId	 *            the ID of the server.	 * @return connection, never <code>null</code>.	 * @throws IOException	 *             if we were unable to open a connection.	 */	public L2CAPConnection connectToServer(final UUID serverId)			throws IOException {		synchronized (DISCOVERY_LOCK) {			connection = null;			exception = null;			for (int tries = 0; tries < 3; tries++) {				serviceTransactionID = discoveryAgent.searchServices(null,						new UUID[] { serverId }, device, this);				synchronized (lock) {					try {						lock.wait();					} catch (InterruptedException e) {						// do nothing					}				}				if (connection != null)					return connection;			}			if (exception == null)				throw new IOException("No server services found"); //$NON-NLS-1$			throw exception;		}	}	/**	 * {@link #connectToServer(UUID)} waits for this object until a service	 * search is completed.	 */	private final Object lock = new Object();	/**	 * Exception is set here by {@link #tryToConnect(ServiceRecord[])} on	 * unsuccesfull connect.	 */	private volatile IOException exception = null;	/**	 * Current active service transaction ID.	 */	private int serviceTransactionID = -1;	/**	 * Connection is set here by {@link #tryToConnect(ServiceRecord[])} on	 * succesfull connect.	 */	private volatile L2CAPConnection connection = null;	/**	 * Client ID given by server to this client. Contains <code>-1</code> on	 * unsuccesfull connect. Valid after the {@link #connectToServer(UUID)}	 * returns with non-<code>null</code> connection.	 */	public volatile byte clientId = -1;	/**	 * Tries to connect to one of the services provided by the server.	 * 	 * @param serviceRecords	 *            list of {@link ServiceRecord} to connect to.	 * @return client ID given by server to this client. Returns <code>-1</code>	 *         on unsuccesfull connect.	 */	private byte tryToConnect(final ServiceRecord[] serviceRecords) {		if (serviceRecords.length == 0)			throw new IllegalArgumentException("Empty serviceRecords"); //$NON-NLS-1$		for (int i = 0; i < serviceRecords.length; i++) {			final ServiceRecord service = serviceRecords[i];			final String url = service.getConnectionURL(					ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);			Logger.debug("ServerInfo.tryToConnect(): Trying " + url, null); //$NON-NLS-1$			try {				final L2CAPConnection connection = (L2CAPConnection) Connector						.open(url);				// test the connection by sending and receiving initialization				// packet.				connection.send(StreamUtils.stringToByteArray(Peer.getDeviceName()));				final byte[] initBuf = new byte[48];				final int bufLen = connection.receive(initBuf);				final DataInputStream in = new DataInputStream(						new ByteArrayInputStream(initBuf, 0, bufLen));				final byte clientId = in.readByte();				// good!				Logger.info("ServerInfo.tryToConnect(): Got connection to " //$NON-NLS-1$						+ url, null);				this.connection = connection;				return clientId;			} catch (IOException ex) {				Logger.debug("ServerInfo.tryToConnect(): Failed to connect to " //$NON-NLS-1$						+ url, ex);				exception = ex;			}		}		Logger.error("ServerInfo.tryToConnect(): Tried " //$NON-NLS-1$				+ serviceRecords.length + " services and failed", null); //$NON-NLS-1$		return -1;	}}

⌨️ 快捷键说明

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