Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Bluetooth в Windows 
:(
    Опции темы
juvf
Дата 22.9.2016, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Как взаимодействовать с БТ из винды? Начал использовать "Windows Sockets Support for Bluetooth" но чото лыжи не едут. Делаю следующий алгоритм с winsock

Код

Код

socket();
connect();
send(sock, array, 8, 0);
shutdown(sock, SD_SEND);
recv();


если в дебаге прошагать, то всё прекрасно работает. создается сокет и конектиться без ошибок. удаленное устройство видит коннект. посылаются данные, удаленое устройство получает их и отвечает. recv() возвращает кол-во принятых байт. как в аптеке.

если без остановки выполнить.... то send() возвращает 8, shutdown() возвращает 0, recv() возвращает 0. Удаленное устройство видит подключение, но не получает ни одного байта. если между этими функциями понаставить пауз секундных, то код выполняется без остановки нормально... уходит запрос и возвращается ответ. Почему без пауз не работает? Если из-за неблокирующего сокета, то как сокет сделать блокирующим?

ps Может вместо этой API есть более годные либы для работы с bluetooth под винды?
PM MAIL   Вверх
feodorv
Дата 22.9.2016, 10:45 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(juvf @  22.9.2016,  10:14 Найти цитируемый пост)
recv() возвращает 0

С неблокирующими сокетами данные же нужно подождать, пока придут. Если просто вызвать recv(), то система заглянет в буфер приёма, увидит, что он пуст, и вернёт 0. Всё правильно. А ждать данные в винде можно через WSAEVENT/WSAWaitForMultipleEvents или через select.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
juvf
Дата 22.9.2016, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



да у меня даже отправки нет.... send(sock, array, 8, 0); видать помещает данные в буфер передачи и сразу вызвращается.... а следом идет shutdown(sock, SD_SEND); Удаленное устройство по БТ не получает ни одного байта.

 
Цитата

 А ждать данные в винде можно через ... select.
 
Я пробовал через селект..... не получилось. Есть пример работы с скоетами через селект?
PM MAIL   Вверх
feodorv
Дата 22.9.2016, 13:15 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(juvf @  22.9.2016,  11:05 Найти цитируемый пост)
видать помещает данные в буфер передачи и сразу вызвращается.... 

Да.

Цитата(juvf @  22.9.2016,  11:05 Найти цитируемый пост)
а следом идет shutdown(sock, SD_SEND);

Оно не должно помешать:
Цитата
If the how parameter is SD_SEND, subsequent calls to the send function are disallowed. For TCP sockets, a FIN will be sent after all data is sent and acknowledged by the receiver.


Цитата(juvf @  22.9.2016,  11:05 Найти цитируемый пост)
Удаленное устройство по БТ не получает ни одного байта.

Это не понятно. Это точно установлено? А в случае с блокируемыми сокетами всё было в порядке?

Цитата(juvf @  22.9.2016,  11:05 Найти цитируемый пост)
Есть пример работы с скоетами через селект? 

Внятного примера у меня не нашлось, давно работаю через события (чего и Вам желаю). Отличия от юниксовского подхода есть (в основном в области обработки ошибок), но мало. В инете примеры найти можно.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
juvf
Дата 22.9.2016, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Цитата

Это не понятно. Это точно установлено? А в случае с блокируемыми сокетами всё было в порядке?
 У меня не было случая с блокируемым сокетом, у меня были случай с паузами между командами. Да, было всё в порядке.

Цитата

Оно не должно помешать:
Цитата

If the how parameter is SD_SEND, subsequent calls to the send function are disallowed. For TCP sockets, a FIN will be sent after all data is sent and acknowledged by the receiver.

 Ну это неизвестно. Для TCP сокета это не мешает. Для БТ сокета чото не работает.

Добавлено через 9 минут и 49 секунд
Цитата

Отличия от юниксовского подхода есть (в основном в области обработки ошибок), но мало. В инете примеры найти можно. 
 в юниковском коде по дефолту сокет блокирующий. для управления блокировать или нет есть метод fcntl(). В API винды такого метода нет. Потмеров полно по юниксу, даже есть по винде для ТСП, но для винды для блютуза не могу найти.
PM MAIL   Вверх
feodorv
Дата 23.9.2016, 12:58 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(juvf @  22.9.2016,  14:03 Найти цитируемый пост)
В API винды такого метода нет.

Найдите в инете "Windows Sockets 2 Application Programming Interface" и узнаете, чего есть в виндах, чего нету  smile  Например, про ioctlsocket(FIONBIO). И что сокет после создания тоже блокирующий. 


Цитата(juvf @  22.9.2016,  14:03 Найти цитируемый пост)
 У меня не было случая с блокируемым сокетом, у меня были случай с паузами между командами. Да, было всё в порядке.

Тогда я ничего не понимаю))) Как у Вас всё это работало на неблокирующих сокетах без селекта или событий?


Цитата(juvf @  22.9.2016,  14:03 Найти цитируемый пост)
для винды для блютуза не могу найти

Тут, увы, мне сказать нечего. С блютусом не работал, опыта нет.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
juvf
Дата 23.9.2016, 13:43 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Цитата

узнаете, чего есть в виндах, чего нету  smile  Например, про ioctlsocket(FIONBIO).
я это знаю.... эти знания не помогают. 

Цитата

socket();
connect();
u_long iMode=0;
ioctlsocket(sock,FIONBIO,&iMode);
send(sock, array, 8, 0);
shutdown(sock, SD_SEND);
recv();
не помогает.

Цитата

И что сокет после создания тоже блокирующий. 
теоретически лошадь - практически упала. может сокет при создании и блокирующий, но только выше приведённый код не работает.
зато такой код работает

Код

socket();
connect();
pause_ms(3000);
send(sock, array, 8, 0);
pause_ms(3000);
shutdown(sock, SD_SEND);
pause_ms(3000);
recv();
из чего я делаю вывод что сокет при создании не блокирующий. хотя эти выводы тоже не верны... т.к. сокет может заблокировался на 10 мс, а блютузу надо больше времени. кстати... как указать сокету сколько времени сокет должен находиться в блокированном состоянии?

ps хотя если сокет вывалится по таймауту, то send или recv тернёт WSAETIMEDOUT, но этого не происходит.
PM MAIL   Вверх
feodorv
Дата 25.9.2016, 13:18 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(juvf @  23.9.2016,  13:43 Найти цитируемый пост)
зато такой код работает

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


Цитата(juvf @  22.9.2016,  14:03 Найти цитируемый пост)
для винды для блютуза не могу найти

Первые ссылки по двум ключевым словам "bluetooth" и "socket" дают искомый результат. Например, http://www.winsocketdotnetworkprogramming....protocol4p.htmlТам же, как получить адрес.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
juvf
Дата 25.9.2016, 13:22 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Цитата

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



Код

#pragma comment(lib, "ws2_32.lib")

DEFINE_GUID(SerialPortServiceClass_UUID,0x00001101,0x0000,0x1000,0x80,0x00,0x00,0x80,0x5F,0x9B,0x34,0xFB);

bool Bloutooth::setConnect(QString &error, const QString &teremName)
{
    WSADATA wsa;
    if( WSAStartup(MAKEWORD(2,2), &wsa) !=0)
        return false;


    sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
    if (sock == INVALID_SOCKET)
    {
        //        //Ошибка
        WSACleanup();
        return false;
    }

    u_long iMode = 0;
    int iResult;
    iResult = ioctlsocket(sock, FIONBIO, &iMode);

    SOCKADDR_BTH sab = {0};
    sab.addressFamily  = AF_BTH;
    sab.btAddr = 0X0007800cfae7;
    sab.serviceClassId = SerialPortServiceClass_UUID;
    sab.port = 1;

    if(  ::connect(sock, (struct sockaddr *)&sab, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR)
    {
        iResult = WSAGetLastError();
        error = qt_error_string(WSAGetLastError());//QString("Error open socket. Code of error: %1 \n%2").arg(iResult).arg(getLastErrorAsString());
        closesocket(sock);
        WSACleanup();
        return false;
    }
    isConnected = true;

    return true;
}


за ссылки спасибо!

Добавлено через 3 минуты и 57 секунд
и до кучи передача и прием

Код

QString Bloutooth::readVersion()
{
    QString replay("");
    char array[100] = {0x80, 8, 0xff, 0x7f, 2, 0x27};
    if(isConnected)
    {
        array[2] = this->getAddress();
        Checksum::addCrc16((unsigned char*)array, 6);
        int iResult;
            iResult = ::send(sock, array, 8, 0);
            if (iResult == SOCKET_ERROR)
            {
                qt_error_string(WSAGetLastError());

                return getLastErrorAsString();
            }


            iResult = shutdown(sock, SD_SEND);

           iResult = ::recv(sock, array, 100, 0);
            if(iResult >= 8)
            {
                array[iResult - 2] = 0;
                replay = QString(&array[6]);
                return replay;
            }
            else if(iResult == 0)
                replay = "Connection closed";
            else
                replay = getLastErrorAsString();
        }
    }
    return replay;
}


Добавлено через 12 минут и 2 секунды
ps забегая вперёд..... вот работая с обычным компортом или с бинарным ТСП сокетом я обмен осуществлял так

-открытие компорта
-отправка запроса
-ожидание ответа
-обработка ответа
-отправка запроса
-приме и отбработка ответа
.....
....
-закрытие порта

как с блютузом и сокетами в этом случае? получается так
-открытие сокета блютуза
-отправка запроса
-закрытие передачи (шатдаун сенд)
-ожидание ответа
-обработка ответа
-... а дальше? можно сразу посылать новый запрос? там был сделан шатдаунд сенд. как после этого делать передачу? или после приема надо сделать шатдаунт приема и делать передачу? или надо открыть и закрыть сокет?
PM MAIL   Вверх
feodorv
Дата 30.9.2016, 06:53 (ссылка)    | (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Прошу прощения за долгое молчание smile 

Здесь можно найти такую фразу: 
Цитата

Bluetooth uses the shutdown() function to disconnect from the remote radio. Bluetooth does not have protocol-level support for the same graceful closes or half-closes that TCP/IP provides.
Так что не понятно, насколько этот shutdown() нужен, хотя его суют во все примеры (может, и не зря). Я бы попробовал без него.


Цитата(juvf @  25.9.2016,  13:22 Найти цитируемый пост)
как с блютузом и сокетами в этом случае? получается так
-открытие сокета блютуза
-отправка запроса
-закрытие передачи (шатдаун сенд)
-ожидание ответа
-обработка ответа
-... а дальше? можно сразу посылать новый запрос? там был сделан шатдаунд сенд. как после этого делать передачу? или после приема надо сделать шатдаунт приема и делать передачу? или надо открыть и закрыть сокет? 

Всё зависит от того, как на той стороне работает сервер. Если он способен только на один запрос-ответ, то придется каждый раз открывать новое соединение, а затем его закрывать. Если же сервер может обрабатывать множественные запросы, то, конечно, можно обойтись одним сокетом.


Очень надеюсь, что у Вас что-нибудь разрешилось за это время smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
juvf
Дата 30.9.2016, 07:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Цитата

Очень надеюсь, что у Вас что-нибудь разрешилось за это время
Спасибо за поддержку.... Нет, не разрешилось. Собираюсь писать в поддержку msdn. Пока работаю с БТ через виртуальный компорт. Но хотелось бы как то напрямую передавать/читать данные. Если что получиться, то отпишусь
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1537 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.