java-如何重写在方法中获取消息的循环

我有一个蓝牙服务器,它从客户端(手机)接收数据.我正在使用的代码如下

@Override
public void run() {
    try {
        this.localDevice = LocalDevice.getLocalDevice();
        this.localDevice.setDiscoverable(DiscoveryAgent.GIAC);

        this.server = (StreamConnectionNotifier) Connector.open(URL);

        while(true) {
            if(this.connection == null) {
                this.connection = this.server.acceptAndOpen();

                System.out.println("INFO: Bluetooth client connected");

                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.openInputStream()));
                this.writer = new BufferedWriter(new OutputStreamWriter(connection.openOutputStream()));

                String line;
                while((line = reader.readLine()) != null) {
                    if(line.equals("--#do:disconnect")) {
                        break;
                    }

                    System.out.println("INFO: Received from Bluetooth: " + line);
                }

                System.out.println("INFO: Client disconnected");
            }
        }
    } catch(BluetoothStateException ex) {
        ex.printStackTrace();
    } catch(IOException ex) {
        ex.printStackTrace();
    }
}

如您所见,我有一个不定式循环来接收消息,直到被告知停止为止.目前,循环接收到所有消息.这是有问题的.使用代码的类是MVC中的模型类.在该类中,我还有一个名为getContacts()的方法.它用于通过蓝牙从电话接收联系人.当服务器发送-#do:getcontacts时,电话被告知要发送联系人.

我需要做的是在getContacts()方法的ArrayList中获取联系人并将其作为方法的返回值返回,以便控制器可以处理联系人.

public ArrayList<Contact> getContacts() {
    ArrayList<Contact> contacts = new ArrayList<>();

    // How do I get the contacts in the ArrayList?

    return contacts;
}

解决方法:

我会给你一些建议.我的示例不是工作代码,而是适合您的工作基础.

首先,我强烈建议您在服务器中使用线程.每次客户端连接到服务器时,您都会创建一个新线程,其参数包含启动它所需的所有数据:

boolean running = true;    //this class variable will allow you to shut down the server correctly

public void stopServer(){    //this method will shut down the server
    this.running = false;
}

public void run() {
    ...

    while(running) {
        // if(this.connection == null) {  // I removed this line since it's unnecessary, or even harmful!
        StreamConnection connection = this.server.acceptAndOpen();  //This line will block until a connection is made...
        System.out.println("INFO: Bluetooth client connected");
        Thread thread = new ServerThread(connection);
        thread.start()              //don't forget exception handling...
    } 
}

在ServerThread类中,您实现了以下这些行来处理客户端(未编译的代码,没有异常处理!):

Class ServerThread extends Thread {
    StreamConnection connection;

    public ServerThread(StreamConnection connection){
        this.connection = connection;
    }

    public void run() {
        ...

        connection.close();     //closing the connection...don't forget exception handling!
        System.out.println("INFO: Client disconnected");
    }
}

此代码的优点是什么?现在,您的服务器可以同时处理一千个客户端.您已经进行了并行化,这就是服务器通常的工作方式!没有线程的服务器就像没有鞋子的袜子…

其次,如果您有Java客户端和Java服务器,则可以使用一种更简单的方法将对象发送到服务器:ObjectOutputStream / ObjectInputStream.您只需将包含联系人的数组(通常将使用ArraList)发送到服务器,然后读取该数组.这是服务器的代码(同样未编译且没有任何异常处理):

Class ServerThread extends Thread {
    StreamConnection connection;

    public ServerThread(StreamConnection connection){
        this.connection = connection;
    }

    public void run() {

        BufferedInputStream bis = new BufferedInputStream(this.connection.openInputStream());
        ObjectInputStream ois = new ObjectInputStream(bis);

        ArrayList contacts = (ArrayList) ois.readObject();  //this is a cast: don't forget exception handling!
        //You could also try the method ois.readUTF(); especially if you wanna use other non-Java clients

        System.out.println("INFO: Received from Bluetooth: " + contacts);
        this.connection.close();    //closing the connection...don't forget exception handling!
        //ois.close();      //do this instead of "this.connection.close()" if you want the connection to be open...i.e. to receive more data

        System.out.println("INFO: Client disconnected");

        //here you do whatever you wanna do with the contacts array, maybe add to your other contacts?
    }
}

在Java中,每个类都是一个对象,包括ArrayList.并且由于对象的末尾将被视为断开连接,因此您无需执行其他任何操作.

第三:您不仅将上述服务器用于蓝牙连接,而且还将WLAN连接用于aso.然后,您可以轻松地启动不同的线程,如伪代码if(connection.isBluetooth()){//从BluetoothThread创建线程},否则if(connection.isWLAN()){//从WLANsThread创建线程}.我不知道您的应用程序是关于什么的,但是也许有一天您想将其扩展到台式机,所以使用WLAN是正确的选择.另外,由于无论如何是蓝牙还是WLAN,无论如何,您都需要在客户端中建立一个验证(“哪些联系人将被发送到哪个服务器?”),因为蓝牙的范围较小,无法为您提供任何安全性.

上一篇:android-通过蓝牙发送文件


下一篇:C#:确定蓝牙适配器是否已打开/关闭(以编程方式)使用的堆栈类型