linux快速释放无效socket连接设置

通过在/etc/sysctl.conf文件中配置net.ipv4.tcp_syncookies=1, net.ipv4.tcp_tw_reuse=1和net.ipv4.tcp_fin_timeout=30,可以加速Linux服务器上无效Socket连接的释放。应用更改后,使用'sysctl -p'命令使配置生效。" 128869587,148831,优快云每日一练难题解析,"['编程挑战', '算法问题', '编程学习', '优快云平台', '数据结构']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在/etc/sysctl.conf中添加

net.ipv4.tcp_syncookies=1

net.ipv4.tcp_tw_reuse=1

net.ipv4.tcp_fin_timeout=30 

 最后记得使用 sysctl   -p 使用配置生效

<think>我们正在处理低功耗蓝牙(BLE)设备的扫描和连接。在Linux中,我们通常使用BlueZ库来实现蓝牙功能。对于BLE设备,我们需要使用Bluez5.x或更高版本,因为它提供了对BLE的支持。步骤:1.扫描BLE设备:使用HCI工具进行扫描,但这里我们使用C代码通过BlueZ提供的API来实现。2.连接设备:在扫描到设备后,我们需要连接设备,然后可以执行GATT操作(发现服务、读写特征等)。注意:BlueZ提供了DBusAPI,但我们也可以使用socket级别的操作(如HCI和L2CAP)。然而,对于BLE,DBusAPI是更高级和常用的方式。但是,用户要求使用C代码,我们可以考虑使用BlueZ提供的HCI层API或者使用GATT库(如gattlib)。不过,BlueZ的CAPI文档较少,通常建议使用DBus,但这里我们尝试使用HCI层和GATT层的CAPI。由于BlueZ的BLEAPI在C语言中比较复杂,并且官方文档较少,我们通常参考BlueZ提供的工具代码(如hcitool,gatttool的源代码)或者使用第三方库如gattlib。但是,用户明确要求C代码,我们将提供两种方式:方式1:使用BlueZ的HCI层API进行扫描(这与经典蓝牙类似,但需要设置BLE扫描参数)方式2:使用gattlib进行连接和GATT操作(这是一个第三方库,简化了BLE操作)由于gattlib已经不再维护,而且BlueZ的API变化较大,这里我们提供一个使用BlueZ的HCI层API进行BLE设备扫描的示例,以及使用socket进行连接连接后操作较为复杂,需要GATT协议知识)。但是,请注意,连接后的GATT操作非常复杂,通常建议使用DBus或者使用BlueZ提供的命令行工具(如bluetoothctl)进行交互。由于时间限制,我们这里只提供扫描BLE设备的代码,并尝试连接(建立L2CAP连接)但不进行GATT操作。对于GATT操作,需要实现一个完整的客户端,这超出了简单示例的范围。扫描BLE设备的步骤:1.打开HCI socket2.设置扫描参数(使用LE扫描)3.开始扫描4.读取扫描结果连接BLE设备的步骤(建立L2CAP连接):1.创建一个L2CAPsocket2.设置目标地址和PSM(对于BLE,PSM通常不使用,而是使用固定的通道,但连接时使用LE地址类型)3.连接但是,BLE连接后,我们需要进行ATT协议交互,这需要实现ATT协议,非常复杂。因此,我们通常使用BlueZ的DBus接口或者gatttool。鉴于以上,我们提供以下代码:1.BLE扫描(使用HCI层)2.连接设备(建立L2CAP连接,通道为ATT通道,即0x0004)注意:连接后,我们只是建立了连接,并没有进行任何GATT操作。要进行GATT操作,需要发送和解析ATT协议包。由于代码较长,我们将分步骤进行。第一步:扫描BLE设备我们将使用HCI层进行LE扫描。设置LE扫描参数并启用扫描,然后读取上报的事件。第二步:连接设备使用L2CAPsocket连接到目标设备的ATT通道(通道号4)。参考代码:注意:此代码需要BlueZ开发文件,并且需要以root权限运行。编译命令:gcc ble_scan_connect.c-oble_scan_connect -lbluetooth由于BLE扫描和连接在BlueZ的C API中较为复杂,我们参考了BlueZ的源代码和示例。以下是代码示例:</think>### Linux C 语言扫描和连接 BLE 设备代码示例 以下是使用 BlueZ 协议栈在 Linux 下扫描和连接低功耗蓝牙(BLE)设备的完整 C 代码实现: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <bluetooth/bluetooth.h> #include <bluetooth/hci.h> #include <bluetooth/hci_lib.h> #include <bluetooth/l2cap.h> #define BLE_SCAN_TIMEOUT 5 // 扫描超时(秒) #define ATT_CID 0x0004 // ATT 通道标识符 // BLE 设备结构体 typedef struct { bdaddr_t bdaddr; int8_t rssi; char name[248]; } ble_device; int main() { // 获取本地蓝牙适配器 ID int dev_id = hci_get_route(NULL); if (dev_id < 0) { perror("找不到蓝牙适配器"); exit(1); } // 打开蓝牙 socket int hci_sock = hci_open_dev(dev_id); if (hci_sock < 0) { perror("打开适配器失败"); exit(1); } // 设置 BLE 扫描参数 struct hci_filter flt; hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_LE_META_EVENT, &flt); if (setsockopt(hci_sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("设置过滤器失败"); close(hci_sock); exit(1); } // 开始 BLE 扫描 le_set_scan_parameters_cp scan_params = { .type = 0x01, // 主动扫描 .interval = htobs(0x0010), .window = htobs(0x0010), .own_bdaddr_type = 0x00, .filter = 0x00 }; le_set_scan_enable_cp scan_enable = { .enable = 0x01, // 启用扫描 .filter_dup = 0x00 // 不过滤重复设备 }; if (hci_le_set_scan_parameters(hci_sock, &scan_params, 1000) < 0) { perror("设置扫描参数失败"); close(hci_sock); exit(1); } if (hci_le_set_scan_enable(hci_sock, &scan_enable, 1000) < 0) { perror("启用扫描失败"); close(hci_sock); exit(1); } // 扫描 BLE 设备 printf("正在扫描BLE设备...\n"); ble_device devices[20]; int device_count = 0; uint8_t buf[HCI_MAX_EVENT_SIZE]; ssize_t len; time_t start_time = time(NULL); while (time(NULL) - start_time < BLE_SCAN_TIMEOUT && device_count < 20) { len = read(hci_sock, buf, sizeof(buf)); if (len < 0) continue; if (buf[0] == HCI_EVENT_PKT && buf[1] == EVT_LE_META_EVENT) { evt_le_meta_event *meta = (evt_le_meta_event *)(buf + 2); if (meta->subevent == EVT_LE_ADVERTISING_REPORT) { le_advertising_info *info = (le_advertising_info *)(meta->data + 1); // 获取设备地址 bacpy(&devices[device_count].bdaddr, &info->bdaddr); devices[device_count].rssi = info->data[info->length]; // 获取设备名称 memset(devices[device_count].name, 0, sizeof(devices[device_count].name)); int name_len = 0; for (int i = 0; i < info->length; ) { uint8_t field_len = info->data[i++]; uint8_t field_type = info->data[i++]; if (field_type == 0x09) { // 完整设备名 name_len = field_len - 1; memcpy(devices[device_count].name, &info->data[i], name_len); break; } i += field_len - 1; } if (name_len == 0) { strcpy(devices[device_count].name, "[未知设备]"); } char addr_str[18]; ba2str(&devices[device_count].bdaddr, addr_str); printf("%d. %s - %s (RSSI: %d)\n", device_count + 1, addr_str, devices[device_count].name, devices[device_count].rssi); device_count++; } } } // 停止扫描 scan_enable.enable = 0x00; hci_le_set_scan_enable(hci_sock, &scan_enable, 1000); if (device_count == 0) { printf("未找到BLE设备\n"); close(hci_sock); exit(0); } // 选择要连接的设备 int choice = 0; printf("\n输入要连接的设备编号: "); scanf("%d", &choice); if (choice < 1 || choice > device_count) { fprintf(stderr, "无效选择\n"); close(hci_sock); exit(1); } choice--; // 调整为0-based索引 // 建立BLE连接 struct sockaddr_l2 addr = {0}; int l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (l2cap_sock < 0) { perror("创建L2CAP socket失败"); close(hci_sock); exit(1); } // 设置L2CAP参数 addr.l2_family = AF_BLUETOOTH; addr.l2_psm = htobs(ATT_CID); // ATT通道 addr.l2_bdaddr_type = BDADDR_LE_PUBLIC; bacpy(&addr.l2_bdaddr, &devices[choice].bdaddr); // 连接设备 char addr_str[18]; ba2str(&devices[choice].bdaddr, addr_str); printf("正在连接 %s (%s)...\n", devices[choice].name, addr_str); if (connect(l2cap_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("连接失败"); } else { printf("成功连接到 %s\n", devices[choice].name); printf("可进行GATT操作...\n"); // 在此处添加GATT操作代码 // 例如: 发现服务、读写特征值等 } // 清理资源 close(l2cap_sock); close(hci_sock); return 0; } ``` ### 关键功能说明 1. **BLE 设备扫描**: - 使用 `hci_le_set_scan_parameters()` 设置低功耗扫描参数 - 通过 `EVT_LE_ADVERTISING_REPORT` 事件捕获广播包 - 解析广播数据获取设备名称和 RSSI 信号强度 2. **BLE 连接建立**: - 创建 L2CAP socket (`PF_BLUETOOTH`) - 使用 ATT 通道标识符 `0x0004` 连接设备 - 设置地址类型为 `BDADDR_LE_PUBLIC`(公共地址) 3. **GATT 操作**: - 连接成功后即可进行 GATT 操作 - 需要实现服务发现、特征值读写等逻辑 - 可使用 BlueZ 的 GATT API 或第三方库如 [Bluetoe](https://gitcode.com/gh_mirrors/bl/bluetoe)[^3] ### 编译与运行 ```bash # 安装依赖 sudo apt install libbluetooth-dev # 编译代码 gcc ble_scan_connect.c -o ble_scan_connect -lbluetooth # 运行程序(需要root权限) sudo ./ble_scan_connect ``` ### 注意事项 1. **权限要求**: - 需要 `CAP_NET_ADMIN` 权限操作蓝牙 - 建议使用 `sudo` 运行程序 2. **地址类型**: - 公共地址:`BDADDR_LE_PUBLIC` - 随机地址:`BDADDR_LE_RANDOM` - 需根据设备类型正确设置 3. **GATT 操作**: - 连接后需实现 GATT 协议交互 - 典型操作流程: ```c 1. 发现主服务 2. 查找特征值 3. 读写特征值 4. 处理通知/指示 ``` 4. **信号处理**: - 实际应用中需处理 `SIGINT` 等信号 - 确保资源正确释放 ### 相关资源推荐 - [BlueZ 官方文档](http://www.bluez.org/development/) - [Linux 蓝牙协议栈架构](https://www.kernel.org/doc/html/latest/networking/bluetooth.html)[^1] - [Bluetoe BLE 框架](https://gitcode.com/gh_mirrors/bl/bluetoe)[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自由软件开发者

有你的鼓励,我会更加努力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值