2013-02-11 155 views
8

我正在为使用Bluecove API的计算机构建一个简单的Java蓝牙服务器。我正在构建一个Android客户端应用程序,但问题似乎源于服务器端应用程序。保持Java蓝牙连接活着

我确定有人已经发布了任何答案,我过去几天严格地尝试了不同的解决方案,并且看到了每个可能的论坛,但我似乎无法保持套接字线程上的连接活着。

从android到计算机建立连接后,我可以交换消息,反之亦然,在计算机之间交换字节后,Bluecove堆栈关闭并关闭套接字连接,即使我没有明确地告诉它connection.close()。

我试图用一段时间(某些语句为true)循环来保持连接活着,并且它不再在接收到第一条消息后关闭套接字,但它不能接收我从我发送的任何后续消息智能手机到我的电脑。虽然它基本上处于活动状态,但当我尝试从智能手机发送它时,它不会收到任何新消息。不知道为什么。

对不起,这是我第一次发布,我不确定为什么代码的第一部分不能正确显示在页面上。

代码进行连接:

public BluetoothServer() 
{ 
    try 
    { 
     service = (StreamConnectionNotifier) 
      Connector.open("btspp://localhost:" + new UUID(0x1101).toString() + 
           ";name=SampleServer"); 

      System.out.println("open connection"); 



      while(runState == true){ 

       connection = (StreamConnection) service.acceptAndOpen(); 

//send a greeting across to android 
        outputStream = connection.openOutputStream(); 
        String greeting = "JSR-82 RFCOMM server says hello"; 
        outputStream.write(greeting.getBytes()); 

//run thread that listens for incoming bytes through socket connection 
       Thread t = new Thread(new ConnectedThread(connection)); 
       t.start(); 

      } 

    } catch(IOException e) {} 
} 

螺纹代号收听传入的数据

public void run() 
{ 
    try 
    {  
      //open input stream to listen to data 
      inputStream = connection.openInputStream();    

      byte buffer[] = new byte[1024]; 
      int bytes_read = inputStream.read(buffer); 

      String received = new String(buffer, 0, bytes_read); 
      System.out.println("received: " + received); 

    } 
     catch(IOException e){} 
} 
+0

您不能从客户端发送多个消息到服务器,但是您能否将多个消息从服务器发送到客户端?哪个循环调用你的run()方法?你能提供这个代码调用run()吗? – 2015-01-11 10:21:45

+0

在过去,我面临着非常类似的问题。但在我的情况下,连接并未关闭,只有IO速度正在放慢(在Android端)。在调试之后,我们发现,经过一段时间的不活动之后,它会在特定超时后发生在Android端(Android切换到电源安全模式),并且此超时不能更改。为了保持连接正常,我们只是定期发送空包(一个字节)。希望它会有所帮助。 – Eugene 2015-03-02 11:49:25

+0

不要只使用空白的try/catch块。在抛出异常时记录它,它会帮助你获得真正的理由。否则,你在猜测。 – Don 2015-03-12 03:57:00

回答

0

可惜我不能尝试你的代码在我的机器上真实的,但我想我看到了你的错误:在你的run()中 - 你从输入流中读取的方法,打印到控制台然后结束。在你的最后一行之后

 System.out.println("received: " + received); 

your run() - 方法结束并且线程被运行时抛弃。 你需要在一段时间(true)或while(running)循环中放置接收。

我修改了你的代码,但在这里,请记住我之前说过的:我无法测试它,所以它完全没有经过测试!

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

import javax.bluetooth.UUID; 
import javax.microedition.io.Connector; 
import javax.microedition.io.StreamConnection; 
import javax.microedition.io.StreamConnectionNotifier; 


public class BluetoothServer { 

    private boolean runState = true; 

    public BluetoothServer(){ 

     try { 
      StreamConnectionNotifier service = (StreamConnectionNotifier) Connector.open("btspp://localhost:" + new UUID(0x1101).toString() + ";name=SampleServer"); 
      System.out.println("open connection"); 

      while(runState == true){ 
       StreamConnection connection = (StreamConnection) service.acceptAndOpen(); 
       new Listener(connection).start(); 
      } 

     } catch(IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private class Listener extends Thread{ 

     private OutputStream os; 
     private InputStream is; 

     public Listener(StreamConnection connection){ 
      try { 
       this.os = connection.openOutputStream(); 
       os.flush(); 
       this.is = connection.openInputStream(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

     public void run(){ 
      StringBuilder builder; 
      try{ 
       String greeting = "JSR-82 RFCOMM server says hello"; 
       os.write(greeting.getBytes()); 

       while(true){ 
        builder = new StringBuilder(); 
        int tmp = 0; 
        while((tmp = is.read()) != -1){ 
         builder.append((char) tmp); 
        } 
        System.out.println("received: " + builder.toString()); 
       } 
      } 
      catch(IOException e){ 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

这里关于我和你的代码的一些一般性意见和想法:

  • 正如你可以看到,在主线程我只接受一个新的连接。一旦客户端连接,我将连接对象提供给线程。然后它开始与客户端进行通信
  • 在Java中,我们通常会在要求它的语句的同一行添加开头的括号,但这仅仅是一个细节而不是必须的。
  • ALLWAYS做一些例外或不捕捉它们。所以最小值是printStacktrace()或者用“throws xException”声明你的方法,但不要忽略和忽略它们。

对于下次你在这里发布的东西,我建议包括所有的导入语句等,它可以帮助那些试图帮助你的人。 (有时,导入可能是造成所有问题的原因,例如,当某人导入java.awt.List而不是java.util时。清单)

我希望我帮你!