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

📄 client.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 javax.bluetooth.L2CAPConnection;import javax.bluetooth.UUID;import net.sf.btw.tools.Logger;/** * <p> * A client helper class that will attempt to connect to the server. Not thread * safe. You can only connect to a single server per one client class instance. * </p> * <p> * Please follow these steps: * </p> * <ul> * <li>Create instance of the object</li> * <li>set {@link #listener}</li> * <li>{@link #connect(ServerInfo) connect} to a single server</li> * <li>{@link #send(byte[]) send} data to server, receive data via the listener</li> * <li>{@link #disconnect()} from the server</li> * </ul> *  * @author Martin Vysny *  */public final class Client extends Peer implements Runnable, IErrorListener {	/**	 * Starts acting as a client.	 * 	 * @param server	 *            server ID	 * @param receiveMTU	 *            maximum size of received packet, see	 *            {@link L2CAPConnection#getReceiveMTU()} for details.	 * @param transmitMTU	 *            maximum size of transmitted packet, see	 *            {@link L2CAPConnection#getTransmitMTU()} for details.	 * @param listener	 *            Listens for client events. Must not be <code>null</code>	 */	public Client(final UUID server, final int receiveMTU,			final int transmitMTU, final IClientListener listener) {		super(server, receiveMTU, transmitMTU, listener);		receiverBuffer = new byte[receiveMTU];	}	/**	 * Tries to connect to given server. The function does not block and returns	 * immediately.	 * 	 * @param server	 *            server to connect.	 */	public void connect(final ServerInfo server) {		checkNotConnected();		this.server = server;		new Thread(this).start();	}	/**	 * We are going to connect to this server.	 */	private volatile ServerInfo server;	/**	 * Connection to server.	 */	private L2CAPConnection connection;	private PacketScheduler scheduler;	/**	 * Lock onto this object when a connection state is changing.	 */	private final Object connectionChangeLock = new Object();	/**	 * Disconnects from the server.	 */	public void disconnect() {		synchronized (connectionChangeLock) {			if (connection != null) {				try {					scheduler.stop();					connection.close();					connection = null;				} catch (Exception e) {					Logger.info("Client.disconnect()", e); //$NON-NLS-1$					invokeErrorOccured(SERVER_ID,							IErrorListener.ERROR_HINT_CLOSING_CONNECTION, null,							e);				}				try {					((IClientListener) listener).disconnected();				} catch (Exception ex) {					invokeErrorOccured(SERVER_ID,							IErrorListener.ERROR_HINT_CLOSING_CONNECTION,							"disconnected()", ex); //$NON-NLS-1$				}				Logger.debug("Client.disconnect(): disconnected", null); //$NON-NLS-1$			}		}	}	private final static Byte ZERO = new Byte((byte)0);	/**	 * Ensures that the client is connected to the server.	 */	void checkConnected() {		if (connection == null)			throw new IllegalArgumentException("Client not connected"); //$NON-NLS-1$	}	/**	 * Ensures that the client is not connected to the server.	 */	void checkNotConnected() {		if (connection != null)			throw new IllegalArgumentException(					"Client connected, disconnect first"); //$NON-NLS-1$	}	/**	 * Received data is placed here.	 */	private final byte[] receiverBuffer;	/**	 * Internal method, not intended to be called by users.	 */	public void run() {		Logger.debug("Client.run(): starting listener", null); //$NON-NLS-1$		try {			try {				synchronized (connectionChangeLock) {					connection = server.connectToServer(serverId);				}				scheduler = new PacketScheduler(this);				scheduler.addRoute(ZERO, connection);			} catch (Exception ex) {				Logger.error("Client.run(): connecting", ex); //$NON-NLS-1$				invokeErrorOccured(Peer.SERVER_ID,						IErrorListener.ERROR_HINT_OPENING_CONNECTION, null, ex);				return;			}			try {				((IClientListener) listener).connected(server.clientId);			} catch (Exception ex) {				invokeErrorOccured(SERVER_ID,						IErrorListener.ERROR_HINT_OPENING_CONNECTION,						"connected()", ex); //$NON-NLS-1$				disconnect();				return;			}			try {				Logger.debug("Client.run(): waiting for data", null); //$NON-NLS-1$				while (true) {					final L2CAPConnection conn = connection;					if (conn == null)						return;					final int bytesReceived = conn.receive(receiverBuffer);					final DataInputStream stream = new DataInputStream(							new ByteArrayInputStream(receiverBuffer, 0,									bytesReceived));					// invoke messageArrived handler					try {						((IClientListener) listener).messageArrived(								receiverBuffer, bytesReceived, stream);					} catch (Exception ex) {						invokeErrorOccured(SERVER_ID,								IErrorListener.ERROR_HINT_COMMUNICATING,								"messageArrived()", ex); //$NON-NLS-1$					}				}			} catch (Exception ex) {				// this exception may be invoked by closing a connection in				// disconnect() method. Check if this is such a case.				boolean isDisconnected = false;				synchronized (connectionChangeLock) {					isDisconnected = (connection == null);				}				Logger.log(isDisconnected ? Logger.LEVEL_DEBUG						: Logger.LEVEL_ERROR, "Client.run()", ex); //$NON-NLS-1$				if (!isDisconnected)					invokeErrorOccured(SERVER_ID,							IErrorListener.ERROR_HINT_COMMUNICATING, null, ex);			}			disconnect();		} finally {			Logger.debug("Client.run(): terminating", null); //$NON-NLS-1$		}	}	/**	 * Sends given byte array to server. Does not block.	 * 	 * @param data	 *            the data to send. You must not modify the array until the	 *            message get sent.	 */	public void send(byte[] data) {		scheduler.sendPacket(ZERO, data);	}	/**	 * Internal method, not intended to be called by users.	 */	public void errorOccured(byte clientID, int errorHint,			final boolean listenerError, Exception ex) {		// scheduler couldn't send packets.		invokeErrorOccured(clientID, errorHint, null, ex);		disconnect();	}}

⌨️ 快捷键说明

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