2014-12-11 74 views
1

我正在使用英特爾Edison上運行的C語言編寫「競速盒」。它可以通過基於藍牙聊天的Android應用發送或接收藍牙數據。一切正常。我可以發送和接收。我可能會失去連接並重新獲取連接並且數據會從C程序流向Android應用程序。除非重新連接,否則一切都很好,我不能再將數據從C發送到Android。我已經將此跟蹤到了read語句,並且我認爲它永遠不會返回值,因爲它永遠不會退出while循環。具體而言,該行:當藍牙連接丟失時,藍牙讀取線程不會退出c

while(bluetooth_up == 1 && (read(client, &aa, 1) == -1)){ 

,當我知道bluetooth_up == 0(另一個線程fprints bluetooth_up,它是0,當藍牙關閉)甚至不會退出。我的結論是,讀擋住了,所以我試圖修復與線

fcntl(s, F_SETFL,sock_flags|O_NONBLOCK); 

藍牙連接藍牙寫線程。但就像我說的,除了這個while循環不會退出,當bluetooth_up爲0.

所有我可以弄清楚的是,讀是阻塞,我無法弄清楚是如何使它不阻塞,所以它將返回-1,while循環可以看到bluetooth_up == 0並退出。

這裏是bluetooth_up的全局定義

volatile int bluetooth_up = 0; 

我將在此欣賞幫助,因爲它需要強大的,我不想要求人們功率循環比賽箱子拿到藍牙再次合作,儘管這確實有效。

void *blueRead(void *arg){ 
    blue_read_up = 1; 
    char aa; 
    char buffer[500]; 
    int idx = 0; 
    printf("\nBlue Read started\n"); 
    fcntl(s, F_SETFL,sock_flags|O_NONBLOCK); 
    while(bluetooth_up == 1){ 
     if (new_blue_read_sentence == 0 && bluetooth_up == 1){ 
      while(bluetooth_up == 1 && (read(client, &aa, 1) == -1)){ 
        if(bluetooth_up == 0){ 
         printf("\nExiting blue read\n"); 
         blue_read_up = 0; 
         return NULL; 
        } 
      } 
      printf("%i",aa); 
      if(aa != '\n') 
      { 
       buffer[idx++] = aa; 
      } 
      else 
      { 
       buffer[idx] = '\n'; 
       buffer[idx + 1] = '\0'; 
       idx = 0; 
       strcpy(blue_read_buffer, buffer); 
       new_blue_read_sentence = 1; 
      } 
     } 
    } 
    printf("\nExiting blue read 2\n"); 
    blue_read_up = 0; 
    return NULL; 
} 

我認爲藍牙連接的代碼是非常標準的,但在這裏它是

 // allocate socket 
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 
    printf("\nsocket = %i\n", s); 

    // bind socket to port 1 of the first available local bluetooth adapter 
    loc_addr.rc_family = AF_BLUETOOTH; 
    loc_addr.rc_bdaddr = *BDADDR_ANY; 
    loc_addr.rc_channel = (uint8_t)1; 
    retval = bind(s, (struct sockaddr*)&loc_addr, sizeof(loc_addr)); 
    printf("\nbind = %i\n", retval); 

    // put socket into listening mode 
    //listen(s, 1); 
    retval = listen(s, 1); 
    printf("\nlisten = %i\n", retval); 

    // accept one connection 
    client = accept(s, (struct sockaddr*)&rem_addr, &opt); 

    sock_flags = fcntl(s,F_GETFL,0); 
    fcntl(s, F_SETFL,sock_flags|O_NONBLOCK); 

    printf("\n1 - client connect = %i socket %i\n", client, s); 
+0

我可以使用pthread_cancel殺死另一個線程的線程,這個線程不會掛斷並且工作正常,但這看起來並不是正確的方式。也許這是,至少它是有效的。 – 2014-12-11 06:57:12

回答

0

你的監聽套接字(S)上設置O_NONBLOCK。試試接受的套接字(客戶端),它是實際正在讀取的套接字。

+0

Android應用程序,說話者,沒有問題。當C應用程序能夠離開循環時,例如通過pthread_cancel,一切都可以正常工作,而無需觸摸Android端。取消解決方案正在工作,我只是不認爲它是乾淨的。 – 2014-12-12 04:39:00