2016-02-11 7 views
-1

Я проверяю свой код для повторного подключения в случае падения соединения. Однако я столкнулся с некоторой ошибкой сегментации после повторного открытия и повторного подключения сокета.C Программирование сокетов: повторное подключение и повторное подключение сокета

#include <pthread.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/socket.h>    //socket 
#include <bluetooth/bluetooth.h> //bluetooth 
#include <bluetooth/rfcomm.h>  //bluetooth 
#include <string.h>     //strlen 
#include <arpa/inet.h>    //inet_addr 

struct BTConnection { 
    int client; 
    int s; 
    int retry; 
}; 

struct BTConnection bt_1; 

void *bt_connect(void *arg); 
void *bt_send(void *arg); 
void *bt_receive(void *arg); 

void *bt_connect(void *arg) 
{ 
    struct BTConnection *connect = (struct BTConnection*)arg; 

    struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 }; 
    char buf[1024] = { 0 }; 
    socklen_t opt = sizeof(rem_addr); 

    // allocate socket 
    connect->s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 

    // 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; 
    bind(connect->s, (struct sockaddr *)&loc_addr, sizeof(loc_addr)); 

    // put socket into listening mode 
    listen(connect->s, 1); 

    // accept one connection 
    connect->client = accept(connect->s, (struct sockaddr *)&rem_addr, &opt); 
    ba2str(&rem_addr.rc_bdaddr, buf); 

    return 0; 
} 

void *bt_send(void *arg) 
{ 
    struct BTConnection *connect = (struct BTConnection*)arg; 
    char buf[1024] = { 0 }; 
    int bytes_read, retry; 

    puts("[Bluetooth] Sending data to device..."); 
    while(1) { 
     ..... 

     pthread_mutex_lock(&mDataMutex); 
     puts("send mutex in"); 
     while(connect->retry != 0); 
     puts("send mutex out"); 
     pthread_mutex_unlock(&mDataMutex); 

     if(write(connect->client, return_msg, strlen(return_msg)) < 0) { 
      .... 
      puts("Error reading from socket"); 
      pthread_mutex_lock(&mDataMutex); 
      puts("send mutex"); 
      if(connect->retry == 0) 
       connect->retry = 2; 
      pthread_mutex_unlock(&mDataMutex); 
      puts("send mutex end"); 

      pthread_mutex_lock(&mDataMutex); 
      if(connect->retry == 2) { 
       close(connect->client); 
       close(connect->s); 
       bt_connect(&connect); 
       connect->retry = 0; 
       puts("send retry success"); 
      } else 
       retry = 1; 
      pthread_mutex_unlock(&mDataMutex); 

      if(retry == 1) 
      { 
       puts("bluetooth send retrying in 8 secs"); 
       sleep(8); 
      } 
     } else 
      retry = 0; 

     // clear buffer 
     memset(return_msg,0,sizeof return_msg); 
     memset(temp,0,sizeof temp); 
     // set to send data every second 
     sleep(1); 
    } 

    return 0; 
} 

void *bt_receive(void *arg) 
{ 
    // similar as above 
} 

int main(void) 
{ 
    bt_1.retry = 0; 
    int rc; 
    void *status; 
    pthread_t bt_connect_thread, bt_send_thread, bt_receive_thread; 
    pthread_attr_t attr; 

    /* Initialize and set thread detached attribute */ 
    pthread_attr_init(&attr); 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 

    // Create BT connect thread and start it 
    rc = pthread_create(&bt_connect_thread, &attr, bt_connect, (void *)&bt_1); 
    if (rc) 
    { 
     printf("ERROR; return code from pthread_create() is %d\n", rc); 
     return (-1); 
    } 

    rc = pthread_join(bt_connect_thread, &status); 
    rc = pthread_create(&bt_send_thread, &attr, bt_send, (void *)&bt_1); 
    rc = pthread_create(&bt_receive_thread, &attr, bt_receive, (void *)&bt_1); 

    rc = pthread_join(bt_send_thread, &status); 
    rc = pthread_join(bt_receive_thread, &status); 
    close(bt_1.client); 
    close(bt_1.s); 
    pthread_attr_destroy(&attr); 

    return 0; 
} 

код может выглядеть немного грязный, посылая и получая часть, как я использую мьютекс для проверки и отладки вывода.

Это выход я получаю:

[Bluetooth] Allocating socket... Done! 
[Bluetooth] Bind socket... Done! 
[Bluetooth] Waiting for incoming connections... 
[Bluetooth] Accepted connection from 44:6D:6C:6D:1B:BC 
[Bluetooth] Bluetooth connection thread completed 
[Bluetooth] Receiving data from device... 
rcv mutex in 
rcv mutex out 
[Bluetooth] Sending data to device... 
send mutex in 
send mutex out 
send mutex in 
send mutex out 
[Bluetooth-Receive] Error reading from socket 
receive mutex 
receive mutex end 
[Bluetooth-Receive] Connections closed. Reconnecting... 
[Bluetooth] Allocating socket... Done! 
[Bluetooth] Bind socket... Done! 
[Bluetooth] Waiting for incoming connections... 
[Bluetooth] Accepted connection from 44:6D:6C:6D:1B:BC 
[Bluetooth] Bluetooth connection thread completed 
Segmentation fault 

Я не уверен, что это неправильно, так как я убедиться, что я закрыть сокет перед повторным открытием. Любая помощь/руководство? Благодаря!

Edit: Не уверен, что если bt_send замятие его, поскольку он не печатать [Bluetooth-Send] Error reading from socket, когда я автоматически отправляя тестовые данные каждый второй ... (и отправлять и получать работают одновременно)

PS. Новое в C и Socket программирования

+3

Если вы запустите этот 'gdb' (или какой-нибудь другой отладчик), он точно скажет вам, какая строка кода вызывает segfault. – e0k

+0

Я бы заподозрил 'close' часть ... –

+0

Вероятно, вы должны проверить возвращаемое значение' bind() 'для отказа. – EOF

ответ

1
void *bt_connect(void *arg) 
{ 
    struct BTConnection *connect = (struct BTConnection*)arg; 

Итак, нам нужно вызвать bt_connect передавая ему указатель на BTConnection.

struct BTConnection *connect = (struct BTConnection*)arg; 
... 
       bt_connect(&connect); 

Поскольку connect является указателем на BTConnection, &connect является указателем на указатель. Так почему мы передаем его bt_connect?

+0

Привет @ david-schwartz благодарит за это. В этом случае, следует ли мне вместо этого передавать глобальную переменную bt_1? Извините, если вам кажется, что вы просите написать код, но он определенно поможет мне лучше, если вы сможете добавить исправленный код, чтобы я мог учиться там и проверить его. – python1010101

+0

Просто удалите '&'. –

+0

большое спасибо, работает как шарм! – python1010101

Смежные вопросы