You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派libwebsockets服务器:如何判断WebSocket连接为本地LAN或远程WAN?

判断LAN/WAN客户端并限制功能(libwebsockets + 树莓派)

绝对可以实现!我之前在嵌入式设备上用libwebsockets做Web服务时,刚好做过类似的客户端来源识别和功能限制逻辑,给你梳理几个可行的方案和实操细节:

1. 核心思路:获取客户端IP + 匹配局域网IP段

首先要从libwebsockets的连接中拿到客户端的IP地址,然后判断这个IP是否属于私有局域网网段(WAN客户端的IP是公网IP,不在这些段里)。

常见的IPv4私有网段:

  • 10.0.0.0/8(10.x.x.x)
  • 172.16.0.0/12(172.16.x.x 到 172.31.x.x)
  • 192.168.0.0/16(192.168.x.x)
    如果需要支持IPv6,可以考虑匹配fc00::/7(唯一本地地址)这类私有网段。

2. 在libwebsockets回调中获取客户端IP

在连接建立的回调(LWS_CALLBACK_ESTABLISHED)里,你可以用libwebsocket_get_peer_addresses函数获取客户端的IP字符串,示例代码片段:

#include <arpa/inet.h>

// 回调函数中的处理逻辑
case LWS_CALLBACK_ESTABLISHED: {
    char client_ip[INET6_ADDRSTRLEN] = {0};
    libwebsocket_get_peer_addresses(wsi, lws_get_socket_fd(wsi), client_ip, sizeof(client_ip), NULL);
    
    // 将IP字符串转为二进制格式,方便网段判断
    struct in_addr addr;
    if (inet_pton(AF_INET, client_ip, &addr) == 1) {
        // 判断是否为局域网IP,结果存入会话数据
        int is_lan = is_private_ip(addr.s_addr);
        struct per_session_data *pss = libwebsocket_user_data(wsi);
        pss->is_local = is_lan;
    }
    break;
}

3. 实现私有IP判断函数

写一个辅助函数来检查IP是否属于私有网段:

int is_private_ip(uint32_t ip) {
    // 转换为主机字节序(inet_pton返回的是网络字节序)
    uint32_t host_ip = ntohl(ip);
    
    // 匹配10.0.0.0/8网段
    if ((host_ip & 0xFF000000) == 0x0A000000) return 1;
    // 匹配172.16.0.0/12网段
    if ((host_ip & 0xFFF00000) == 0xAC100000) return 1;
    // 匹配192.168.0.0/16网段
    if ((host_ip & 0xFFFF0000) == 0xC0A80000) return 1;
    
    // 如需支持IPv6,在这里扩展判断逻辑
    return 0;
}

4. 根据客户端来源限制功能

在后续的请求处理回调中(比如LWS_CALLBACK_RECEIVE、LWS_CALLBACK_HTTP),从会话数据中取出is_local标记,分支处理不同来源的请求:

case LWS_CALLBACK_HTTP: {
    struct per_session_data *pss = libwebsocket_user_data(wsi);
    if (!pss->is_local) {
        // WAN客户端,限制功能:返回权限不足或隐藏敏感接口
        const char *forbidden = "HTTP/1.1 403 Forbidden\r\nContent-Length: 13\r\n\r\nAccess Denied";
        libwebsockets_write(wsi, (unsigned char*)forbidden, strlen(forbidden), LWS_WRITE_HTTP);
        return -1; // 终止当前请求
    }
    // LAN客户端,正常执行业务逻辑
    // ... 你的页面渲染/API处理代码 ...
    break;
}

注意事项

  • 即使树莓派在路由器NAT后面,端口转发后树莓派仍然能拿到客户端的真实IP(公网/局域网),判断逻辑不受影响。
  • 可以把允许的LAN网段做成可配置项(比如写入配置文件),后续修改网段更灵活。
  • 如果需要支持IPv6,记得扩展is_private_ip函数,适配对应的私有IPv6网段规则。

内容的提问来源于stack exchange,提问作者user2766918

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:23:19