2014-12-11 101 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