将 android 蓝牙客户端套接字连接到 ubuntu 服务器套接字时出现问题

2024-05-15

我正在编写一个 Android 应用程序,它应该通过蓝牙与服务器交换数据,服务器端位于运行 Ubuntu 的 PC 上,使用 bluez 库,用 C(或 C++)编写。

当我尝试连接到 PC 上的服务器套接字时,我的 Android 应用程序失败 (IOException)。

这基本上是我在java代码中的内容(在Android中,完整的eclipse项目在这里:http://dl.dropbox.com/u/2968234/ThinBTClient.zip http://dl.dropbox.com/u/2968234/ThinBTClient.zip)

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static String address = "00:02:72:B2:85:C7";  // Hard coded for simplicity
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;

..... 
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
btSocket.connect(); // This throws IOException after a timeout of 10seconds or so.

在服务器端(在 Ubuntu 8.10 中),我基本上按照示例 bluez/sdp-register.c 中描述的方式设置了一个蓝牙服务器套接字

下面是我的 C++ 程序。要编译它,请执行以下操作:

g++ -I/usr/include/glib-2.0/ -I/usr/lib/glib-2.0/include -o bt_server bt_server.cpp -lbluetooth

我可以成功地执行相反的操作,即在 Android 中创建服务器套接字并从 Linux 进行连接,但这不是我想要做的! 我认为这个问题与我的 Ubuntu 配置有关,但我似乎无法弄清楚这个问题,任何帮助将不胜感激!

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sco.h>
#include <bluetooth/sdp_lib.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/l2cap.h>
#include <glib.h>

sdp_session_t* register_service(uint8_t rfcomm_channel)
{
 // Adapted from http://www.btessentials.com/examples/bluez/sdp-register.c
    uint32_t svc_uuid_int[] = {   0x01110000, 0x00100000, 0x80000080, 0xFB349B5F };
    const char *service_name = "Roto-Rooter Data Router";
    const char *svc_dsc = "An experimental plumbing router";
    const char *service_prov = "Roto-Rooter";

    uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid,
           svc_class_uuid;
    sdp_list_t *l2cap_list = 0,
               *rfcomm_list = 0,
               *root_list = 0,
               *proto_list = 0,
               *access_proto_list = 0,
               *svc_class_list = 0,
               *profile_list = 0;
    sdp_data_t *channel = 0;
    sdp_profile_desc_t profile;
    sdp_record_t record = { 0 };
    sdp_session_t *session = 0;

    // set the general service ID
    sdp_uuid128_create( &svc_uuid, &svc_uuid_int );
    sdp_set_service_id( &record, svc_uuid );

    char str[256] = "";
    sdp_uuid2strn(&svc_uuid, str, 256);
    printf("Registering UUID %s\n", str);

    // set the service class
    sdp_uuid16_create(&svc_class_uuid, SERIAL_PORT_SVCLASS_ID);
    svc_class_list = sdp_list_append(0, &svc_class_uuid);
    sdp_set_service_classes(&record, svc_class_list);

    // set the Bluetooth profile information
    sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
    profile.version = 0x0100;
    profile_list = sdp_list_append(0, &profile);
    sdp_set_profile_descs(&record, profile_list);

    // make the service record publicly browsable
    sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
    root_list = sdp_list_append(0, &root_uuid);
    sdp_set_browse_groups( &record, root_list );

    // set l2cap information
    sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
    l2cap_list = sdp_list_append( 0, &l2cap_uuid );
    proto_list = sdp_list_append( 0, l2cap_list );

    // register the RFCOMM channel for RFCOMM sockets
    sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
    channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel);
    rfcomm_list = sdp_list_append( 0, &rfcomm_uuid );
    sdp_list_append( rfcomm_list, channel );
    sdp_list_append( proto_list, rfcomm_list );

    access_proto_list = sdp_list_append( 0, proto_list );
    sdp_set_access_protos( &record, access_proto_list );

    // set the name, provider, and description
    sdp_set_info_attr(&record, service_name, service_prov, svc_dsc);

    // connect to the local SDP server, register the service record,
    // and disconnect
    session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
    sdp_record_register(session, &record, 0);

    // cleanup
    sdp_data_free( channel );
    sdp_list_free( l2cap_list, 0 );
    sdp_list_free( rfcomm_list, 0 );
    sdp_list_free( root_list, 0 );
    sdp_list_free( access_proto_list, 0 );
    sdp_list_free( svc_class_list, 0 );
    sdp_list_free( profile_list, 0 );

    return session;
}

int main(int argc, char **argv)
{
    int port = 3;
    sdp_session_t* session = register_service(port);


    struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
    char buf[1024] = { 0 };
    int s, client, bytes_read;
    socklen_t opt = sizeof(rem_addr);
    // allocate socket
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
    printf("socket() returned %d\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) port;
    int r;
    r = bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
    printf("bind() on channel %d returned %d\n", port, r);

    // put socket into listening mode
    r = listen(s, 1);
    printf("listen() returned %d\n", r);

    //sdpRegisterL2cap(port);

    // accept one connection
    printf("calling accept()\n");
    client = accept(s, (struct sockaddr *)&rem_addr, &opt);
    printf("accept() returned %d\n", client);

    ba2str( &rem_addr.rc_bdaddr, buf );
    fprintf(stderr, "accepted connection from %s\n", buf);
    memset(buf, 0, sizeof(buf));

    // read data from the client
    bytes_read = read(client, buf, sizeof(buf));
    if( bytes_read > 0 ) {
        printf("received [%s]\n", buf);
    }

    // close connection
    close(client);
    close(s);
    sdp_close( session );

    return 0;
}

确保在您的 Ubuntu 服务器上,您正在创建的服务器套接字已在 SDP 中注册,且 UUID 与您的客户端尝试连接的 UUID 相同。

您可以使用以下命令进行 sdp 查找/转储$ sdptool browse 00:02:72:B2:85:C7但你必须从另一台计算机上运行它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 android 蓝牙客户端套接字连接到 ubuntu 服务器套接字时出现问题 的相关文章

随机推荐

  • 在映射器的单个输出上运行多个减速器

    我正在使用地图缩减实现左连接功能 左侧有大约 6 亿条记录 右侧有大约 2300 万条记录 在映射器中 我使用左连接条件中使用的列来创建键 并将键值输出从映射器传递到减速器 我遇到性能问题 因为两个表中的值数量都很高的映射器键很少 例如分别
  • OpenArgs 为空问题

    我正在使用OpenArgs使用时发送值的参数DoCmd OpenForm DoCmd OpenForm frmSetOther acNormal acFormAdd acDialog value 然后我用Me OpenArgs在打开的表格内
  • 从元素中删除 jquery imgareaselect 插件

    所以我使用这个简洁的 jquery 插件http odyniec net projects imgareaselect http odyniec net projects imgareaselect 它工作正常 但我用 jquery ui
  • 如何在 Google App Engine 的 Python 中获取 StringProperty 的值?

    如何获取 nbd Model 的值 我想返回由多个字段组成的描述 但我无法让它工作 这是我的班级代码 class User ndb Model name ndb StringProperty email ndb StringProperty
  • 当 MIDL 无法创建 tlb 时该怎么办?

    我正在尝试创建一个 C inproc 服务器sbtsv idl 它包含在 Windows 8 SDK 中 几乎我的每一个指示 https stackoverflow com questions 1307675 convert interfa
  • 执行页面的 javascript 后保存页面的 html 输出

    我正在尝试抓取一个网站 它首先加载 html js 使用js修改表单输入字段 然后使用POST 如何获得 POSTed 页面的最终 html 输出 我尝试使用 phantomjs 执行此操作 但它似乎只有渲染图像文件的选项 谷歌搜索表明这应
  • 在使用第三方东西时如何保持 Browserify 包大小合理(如果重要的话通过 grunt )

    我正在尝试捆绑我自己的代码 A 该代码又使用 2 个第三方组件 B 和 C 其中 C 也需要 B 据我所知 所有内容都是使用 CommonJS 节点样式模块编写的 捆绑后单独使用的价格为 60K B 是单独包含的 并假定是全局的 我通过在构
  • css 字体 twitter 像关闭按钮一样,我错过了什么?

    twitter 有一个关闭按钮 它是单个字符 x 我需要类似的东西 但是在我检查之后 span x span 我按照 firebug 告诉我的那样创建 css 规则 close button font family Tahoma Arial
  • GLSL NVidia 方形神器

    当 GLSL 着色器在以下 GPU 上生成不正确的图像时 我遇到了问题 GT 430 GT 770 GTX 570显卡760 但在这些上正常工作 英特尔高清显卡 2500英特尔高清4000英特尔4400显卡740MRadeon HD 631
  • htaccess 重写 url 删除子目录

    我正在尝试重写 http www example com directory folder to http www example com directory htaccess 文件位于directory 这是我的 htaccess 文件
  • TextView 宽度匹配drawableTop 宽度

    有什么办法可以使TextView width匹配复合可绘制宽度 XML 例如对于 xml 代码
  • 这个按位运算如何检查 2 的幂?

    我正在看一些应该很简单的代码 但我的数学在这里严重失败 下面是一个使用以下条件检查数字是否为 2 的幂的条件 if num 1 num num 1 make num pow of 2 我的问题是 如何在 num 和 num 1 之间使用按位
  • 在正常运行时间较长后,服务器端 SignalR 连接失败

    我在 StackOverflow 上搜索了许多与 SignalR 连接相关的其他问题 但似乎都不适用于我的具体情况 我有一个使用 SignalR 集线器的应用程序 客户端可以使用两种方法连接到集线器 通过使用底层客户端连接到集线器的 NET
  • 在 Angular 单元测试中应该如何处理运行块?

    我的理解是 当您在 Angular 单元测试中加载模块时 run块被调用 我认为如果你正在测试一个组件 你不会想同时测试run块 因为unit测试应该只是测试一个unit 真的吗 如果是的话有什么办法可以防止run阻止运行 我的研究让我认为
  • iOS 11 浮动 TableView 标题

    有一个应用程序包含多个部分 展开 时每个部分有几行 折叠 时没有 每个部分都有一个部分标题 使用以下子类重用它们UITableViewHeaderFooterView等等 到目前为止一切顺利 然后在 iOS 11 中 我使用了可视化调试器
  • 如何使用 Python 裁剪图像中的矩形

    谁能给我关于如何裁剪两个矩形框并保存它的建议 我已经尝试过这段代码 但效果不佳 import cv2 import numpy as np Run the code with the image name keep pressing spa
  • Runtime.exec 处理包含多个空格的参数

    我怎样才能进行以下运行 public class ExecTest public static void main String args try Notice the multiple spaces in the argument Str
  • Microsoft Office Url 协议的详细信息?

    Microsoft Office 文档在客户端计算机上注册自定义 url 协议 SharePoint 特别使用此功能 例如 如果我打开一个 Excel 文件 我会看到对此 url 的调用 ms excel ofv u https mycor
  • 如何向 Time.now 添加两周?

    如何在 Ruby 中向当前 Time now 添加两周 我有一个使用 DataMapper 的小型 Sinatra 项目 在保存之前 我有一个字段填充了当前时间加上两周 但未按需要工作 任何帮助是极大的赞赏 我收到以下错误 NoMethod
  • 将 android 蓝牙客户端套接字连接到 ubuntu 服务器套接字时出现问题

    我正在编写一个 Android 应用程序 它应该通过蓝牙与服务器交换数据 服务器端位于运行 Ubuntu 的 PC 上 使用 bluez 库 用 C 或 C 编写 当我尝试连接到 PC 上的服务器套接字时 我的 Android 应用程序失败