📄 serverbox.java
字号:
package midlet.bluetoothone;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
/**
* <p>蓝牙入门示例 --- 服务端应用代码</p>
*
* @author 刘光辉
* @version 2009.02.05
*/
public class ServerBox extends TextBox implements Runnable , CommandListener{
private static final Command CMD_OK = new Command("开启服务",Command.OK,0);
private static final Command CMD_CANCEL = new Command("终止服务",Command.CANCEL,0);
private static final Command CMD_BACK = new Command("返回",Command.BACK,1);
//JSR-82规范定义蓝牙无线技术
private LocalDevice localDevice;
private ServiceRecord sRecord;
//StreamConnectionNotifier接口定义了一个连接通知程序必须的能力
private StreamConnectionNotifier scNotifier;
//ClientProcessor自定义内部类
private ClientProcessor cProcessor;
private BluetoothMIDlet btMIDlet;
//响应服务的UUID
private static final UUID ECHO_SERVER_UUID = new UUID("F0E0D0C0B0A000908070605040302010", false);
private boolean isClosed;
/**
* <p>服务端构造函数<p>
*
*/
public ServerBox(BluetoothMIDlet btMIDlet) {
super("蓝牙服务端", "", 500, TextField.ANY);
this.btMIDlet = btMIDlet;
this.addCommand(CMD_OK);
this.addCommand(CMD_BACK);
this.setCommandListener(this);
}
/**
* <p>服务端线程主体方法<p>
*
*/
public void run() {
boolean isBTReady = false;
try{
localDevice = LocalDevice.getLocalDevice();
//DiscoveryAgent.GIAC == 10390323
if(!localDevice.setDiscoverable(DiscoveryAgent.GIAC)){
showInfo("无法设置设备发现模式");
return;
}
//准备一个URL来创建一个notifier
StringBuffer url = new StringBuffer("btspp://");
//指定这个URL是一个server
url.append("localhost").append(":");
//添加UUID识别这个service
url.append(ECHO_SERVER_UUID.toString());
//给服务添加姓名
url.append(";name=Echo Server");
//要求所有的客户端是authorize=false
//authorize=true一些设备失败
url.append(";authorize=false");
//创建notifier
scNotifier = (StreamConnectionNotifier) Connector.open(url.toString());
sRecord = localDevice.getRecord(scNotifier);
isBTReady = true;
}catch(BluetoothStateException bse){
bse.printStackTrace();
}catch (IOException ioe) {
ioe.printStackTrace();
}
if(isBTReady){
showInfo("初始化成功,等待连接");
this.removeCommand(CMD_OK);
this.removeCommand(CMD_BACK);
this.addCommand(CMD_CANCEL);
}
else
{
showInfo("初始化失败,退出");
return;
}
// 生成服务端服务线程对象
cProcessor = new ClientProcessor();
//启动连接
while(!isClosed){
StreamConnection sconn = null;
try{
sconn = scNotifier.acceptAndOpen();
}catch(IOException e){
continue;
}
cProcessor.addConnection(sconn);
}
}
/**
* <p>命令处理<p>
* @param c
* @param d
*/
public void commandAction(Command c, Displayable d) {
if(c == CMD_OK){
//发布service
publishService();
}
else if(c == CMD_CANCEL){
cancelService();
}
else{
cancelService();
btMIDlet.showMainMenu();
}
}
/**
* <p>发布服务<p>
* @param s
*/
public void publishService(){
isClosed = false;
this.setString(null);
new Thread(this).start();
}
/**
* <p>终止服务<p>
* @param s
*/
public void cancelService(){
isClosed = true;
showInfo("服务终止");
this.removeCommand(CMD_CANCEL);
this.addCommand(CMD_OK);
this.addCommand(CMD_BACK);
}
/**
* <p>内部类 --- 服务端服务线程</p>
*
*/
private class ClientProcessor implements Runnable{
private Thread processorThread;
private Vector queue = new Vector();
// private boolean isOk = true;
ClientProcessor()
{
processorThread = new Thread(this);
processorThread.start();
}
public void run() {
while(!isClosed){
synchronized(this){
if(queue.size() == 0){
try{
//阻塞,直到有新客户连接
wait();
}catch(InterruptedException e){
}
}
}
//处理连接队列
StreamConnection sconn ;
synchronized(this){
if(isClosed){
return;
}
sconn = (StreamConnection) queue.firstElement();
queue.removeElementAt(0);
processConnection(sconn);
}
}
}
/**
* 往连接队列添加新连接,同时唤醒处理线程
* @param conn
*/
void addConnection(StreamConnection conn)
{
synchronized (this)
{
queue.addElement(conn);
notify();
}
}
}
/**
* <p>显示消息<p>
* @param s
*/
private void showInfo(String s){
StringBuffer sb = new StringBuffer(this.getString());
if(sb.length() > 0){
sb.append("\n");
}
sb.append(s);
this.setString(sb.toString());
}
/**
* <p>处理客户端连接<p>
* @param conn
*/
private void processConnection(StreamConnection conn){
// 读取输入
String inputString = readInputString(conn);
//生成响应
String outputString = inputString.toUpperCase();
//输出响应
sendOutputData(outputString, conn);
try{
conn.close();
}catch (IOException e)
{
}
showInfo("客户端输入:" + inputString + ",已成功响应!");
}
/**
* <p>从StreamConnection读取输入<p>
* @param conn
* @return
*/
private String readInputString(StreamConnection conn) {
String inputString = null;
try{
DataInputStream dis = conn.openDataInputStream();
inputString = dis.readUTF();
dis.close();
}catch(IOException e){
}
return inputString;
}
/**
* <p>输出响应<p>
* @param outputData
* @param conn
*/
private void sendOutputData(String outputData, StreamConnection conn){
try{
DataOutputStream dos = conn.openDataOutputStream();
dos.writeUTF(outputData);
dos.close();
}catch(IOException e){
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -