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

📄 client.java

📁 J2ME的游戏原代码!希望能帮助有需要帮助的师兄弟们!..
💻 JAVA
字号:
/*
 *客户端
 *作者:肖昶
 *
*/
package fivegame;

import java.io.*;
import java.util.Vector;
import javax.bluetooth.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;

public class Client extends Form implements CommandListener, Runnable,
		DiscoveryListener {

	private Vector devices = null;// 设备列表
	private Vector services = null;// 服务列表
	private int transIDs[] = null;// 用来存放搜索到的每个设备的服务搜索transaction ID
	private StreamConnection conn = null;// 连接
	private DataOutputStream dos = null;// 输出流
	private DataInputStream dis = null;// 输入流
	private DiscoveryAgent da = null;// 本地设备代理
	private ChoiceGroup cgHosts = null;// 所有服务主机列表
	private static final UUID serviceUUID = new UUID(
			"da822f1b1b4d40c397c36286c753de77", false);// 服务唯一标识
	private Command connectCmd = null;// 连接命令
	private Command backCmd = null;// 返回命令

	public static Client instance = null;// 本类自身实例
	private static Thread tClient = null;// 引用本类主体线程(本类继承至Runnable可以向上转型至Thread)
	private static ConnectThread connectThread = null;// 连接线程

	// 构造函数
	public Client() {
		super("客户端");
		devices = new Vector(10);// 设备列表
		services = new Vector(10);// 服务列表
		backCmd = new Command("返回", 2, 1);
		addCommand(backCmd);
		setCommandListener(this);
	}

	// 主线程,用来搜索服务
	public synchronized void run() {
		Gauge gauge = new Gauge("开始搜索蓝牙设备...", false, -1, 2);
		append(gauge);// 提示滚动条
		boolean isBTReady = false;// 本地设备代理是否就绪
		try {
			LocalDevice localdDevice = LocalDevice.getLocalDevice();// 获取本地设备
			da = localdDevice.getDiscoveryAgent();// 获取本地设备代理
			isBTReady = true;// 本地设备代理就绪
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (!isBTReady) {// 本地设备代理未就绪
			instance = null;
			System.gc();
			Alert refuseInfo = new Alert("错误", "蓝牙不可用!", null, AlertType.INFO);
			FiveGame.display.setCurrent(refuseInfo, SelectList.getInstance());
			return;
		}
		// 开始搜索设备
		try {
			da.startInquiry(DiscoveryAgent.GIAC, this);// 开始搜索设备,搜索到设备时自动调用deviceDiscovered(RemoteDevice,DeviceClass)函数
			// 搜索完毕后将自动调用inquiryCompleted(int)函数
		} catch (BluetoothStateException e) {
			e.printStackTrace();
		}
		try {
			wait();// 阻塞,等待设备搜索完毕
		} catch (InterruptedException e) {
			e.printStackTrace();
			System.out.println("搜索设备等待中断");
		}
		if (devices.size() == 0) {// 未发现任何设备
			instance = null;
			System.gc();
			Alert refuseInfo = new Alert("搜索失败", "没有找到蓝牙设备!", null,
					AlertType.INFO);
			FiveGame.display.setCurrent(refuseInfo, SelectList.getInstance());
			return;
		}
		append("蓝牙设备搜索完毕,共找到:" + devices.size() + "个蓝牙设备...\n下面开始搜索服务...\n");
		// 开始搜索服务
		UUID uuidSet[] = new UUID[2];// 用于搜索的UUID集合
		uuidSet[0] = new UUID(0x1101);// 搜索serial port protocol的服务
		uuidSet[1] = serviceUUID;// 搜索指定的服务
		transIDs = new int[devices.size()];// 用来存放搜索到的每个设备的服务搜索transaction ID
		for (int i = 0; i < devices.size(); i++) {
			RemoteDevice rd = (RemoteDevice) devices.elementAt(i);// 对每一个找到的设备
			try {
				transIDs[i] = da.searchServices(null, uuidSet, rd, this);// 开始搜索服务,搜索到服务时自动调用servicesDiscovered(int,ServiceRecord[])函数
				// 搜索完毕后将自动调用serviceSearchCompleted(int, int)函数
			} catch (BluetoothStateException e) {
				e.printStackTrace();
			}
		}
		try {
			wait();// 阻塞,等待服务搜索完毕
		} catch (InterruptedException e) {
			e.printStackTrace();
			System.out.println("搜索服务等待中断");
		}
		// 服务搜索完毕
		if (services.size() == 0) {// 未找到任何服务
			instance = null;
			System.gc();
			Alert refuseInfo = new Alert("搜索失败", "没有找到任何服务!", null,
					AlertType.INFO);
			FiveGame.display.setCurrent(refuseInfo, SelectList.getInstance());
			return;
		}
		append("服务搜索完毕,共找到:" + services.size() + "个服务...\n请选择服务...");
		String hosts[] = new String[services.size()];// 提供服务的远程主机设备列表
		for (int i = 0; i < services.size(); i++) {
			try {
				hosts[i] = ((RemoteDevice) devices.elementAt(i))
						.getFriendlyName(false);// 获取提供服务的远程主机设备列表
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		delete(0);// 移除提示滚动条
		cgHosts = new ChoiceGroup("服务器列表", 1, hosts, null);// 把可连接的主机以ChoiceGroup形式列出
		connectCmd = new Command("连接", 4, 1);// 加入连接命令
		append(cgHosts);
		addCommand(connectCmd);
	}

	// 搜索到设备时该函数自动调用
	public void deviceDiscovered(RemoteDevice rd, DeviceClass dc) {
		if (devices.indexOf(rd) == -1)// 当前搜索到的设备没有被加入到设备集合中则加入
			devices.addElement(rd);// 把当前搜索到的设备加入到设备集合中
	}

	// 设备搜索完毕后该函数将自动调用
	public void inquiryCompleted(int arg0) {
		synchronized (this) {
			notify();// 唤醒线程继续运行run()接下来的代码
		}
	}

	// 搜索到服务时该函数自动调用
	public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
		for (int i = 0; i < servRecord.length; i++)
			// 搜索到的是该设备所有指定服务的集合
			services.addElement(servRecord[i]);// 加入服务集合中
	}

	// 服务搜索完毕后该函数将自动调用
	public void serviceSearchCompleted(int transID, int arg1) {
		for (int i = 0; i < transIDs.length; i++) {
			if (transIDs[i] == transID) {// 符合这个条件说明该设备的服务已被搜索
				transIDs[i] = -1;// 用来标志该设备设备的服务已被搜索
				break;
			}
		}
		boolean finished = true;// 标志所有设备的服务均已搜索完毕
		for (int i = 0; i < transIDs.length; i++) {
			if (transIDs[i] != -1) {// 有设备的服务还没有被搜索
				finished = false;// 标志置为false
				break;
			}
		}
		if (finished)// 如果所有设备的服务均已搜索完毕
			synchronized (this) {
				notify();// 唤醒线程继续运行run()接下来的代码
			}
	}

	// 命令动作响应, CommandListener接口必须实现的方法
	public void commandAction(Command c, Displayable d) {
		if (c == backCmd) {// 返回命令
			da.cancelInquiry(this);// 取消搜索
			if (tClient != null)
				tClient.interrupt();// 若还在搜索则中断搜索线程
			if (connectThread != null)
				connectThread.interrupt();// 若正在连接则中断连接线程
			try {// 关闭所有连接
				if (dos != null)
					dos.close();
				if (dis != null)
					dis.close();
				if (conn != null)
					conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			instance = null;
			System.gc();
			FiveGame.display.setCurrent(SelectList.getInstance());
		} else if (c == connectCmd) {// 连接命令
			deleteAll();
			append(new StringItem("提示:", "等待服务器回应..."));
			removeCommand(connectCmd);// 连接命令
			connectThread = new ConnectThread();// 连接线程
			connectThread.start();// 开始连接
		}
	}

	// 内部类,是用来连接目标主机的线程
	private class ConnectThread extends Thread {
		public void run() {
			int i = cgHosts.getSelectedIndex();
			ServiceRecord sr = (ServiceRecord) services.elementAt(i);// 目标服务
			String url = sr.getConnectionURL(0, false);// 获取连接url
			try {
				conn = (StreamConnection) Connector.open(url);// 打开连接
				dis = conn.openDataInputStream();// 打开数据输入
				dos = conn.openDataOutputStream();// 打开数据输出
				boolean authorized = dis.readBoolean();// 读取目标主机发回的认证信息
				if (authorized) {// 如果目标主机同意连接
					conn.close();// 关闭
					MainMenu.instance = null;
					SelectList.instance = null;
					System.gc();
					// 通讯连接控制器初始化
					ConnectionControler.initConnCtrl(dis, dos);
					FiveGame.display.setCurrent(MainGame.getInstance(false));// 转至游戏画面,false标识是以客户端方式进入
				} else {// 目标主机拒绝连接
					// 关闭所有连接
					dos.close();
					dis.close();
					conn.close();
					instance = null;
					System.gc();
					Alert refuseInfo = new Alert("连接失败", "服务器拒绝,无法连接!", null,
							AlertType.INFO);
					FiveGame.display.setCurrent(refuseInfo, SelectList
							.getInstance());
				}
			} catch (Exception e) {// 连接异常,包括服务器掉线或用户主动取消连接都会引发该异常
				try {// 关闭所有连接
					if (dos != null)
						dos.close();
					if (dis != null)
						dis.close();
					if (conn != null)
						conn.close();
				} catch (Exception e1) {
					e1.printStackTrace();
				}
				instance = null;
				System.gc();
				Alert refuseInfo = new Alert("连接失败", "服务器不可用或被用户取消连接!", null,
						AlertType.INFO);
				FiveGame.display.setCurrent(refuseInfo, SelectList
						.getInstance());
			}
		}
	}

	// 返回本类的实例
	public static final Client getInstance() {
		if (instance == null)
			instance = new Client();
		tClient = new Thread(instance);
		tClient.start();// 开始搜索 ,调用主线程run()
		return instance;
	}
}

⌨️ 快捷键说明

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