2013-02-11 98 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時。清單)

我希望我幫你!