1

我目前使用的是 Esp32,除了 wifi 之外,它还提供以太网接口。我正在使用带有 FreeRTOS 的 esp-idf v3.3。

为了使用它,我包含了“esp_eth.h”库(https://docs.espressif.com/projects/esp-idf/en/release-v3.1/api-reference/ethernet/esp_eth.html#api-reference -phy-lan8720)。

我想根据我想做的事情同时使用 Wifi 和以太网接口,但是选择使用哪个接口,有没有办法?

实际使用是通过以太网接口接收命令(例如要ping的站点),通过wifi接口ping服务器并将ping结果返回以太网接口。如何选择要使用的接口(我不希望通过以太网进行 ping 或响应通过 wifi)。

@edit:我找到了 netif_set_default(struct netif * netif) 方法,但我不知道这是否是选择用于特定操作的接口的最佳方法(我应该从一个接口切换到另一个接口)

4

1 回答 1

0

只需获取以太网接口的 IP,然后将套接字绑定到该 IP 地址。

    struct in_addr iaddr = {0};
#if USE_ANY_IF
    // Bind the socket to any address
    iaddr.s_addr = htonl(INADDR_ANY); 
#else
    // bind only to the Ethernet interface
    tcpip_adapter_ip_info_t ip_info = {0};
    tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip_info);
    inet_addr_from_ip4addr(&iaddr, &ip_info.ip);
#endif

然后用它来绑定一个socket,例如:

static int create_multicast_ipv4_socket(struct in_addr bind_iaddr)
{
    struct sockaddr_in saddr = {0};
    int sock = -1;
    int err = 0;
    char addrbuf[32] = {0};

    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (sock < 0)
    {
        ESP_LOGE(V4TAG, "Failed to create socket. Error %d", errno);
        return -1;
    }

    saddr.sin_addr.s_addr = bind_iaddr.s_addr; // what interface IP to bind to.  Can be htonl(INADDR_ANY)
    saddr.sin_family = PF_INET;
    saddr.sin_port = htons(UDP_PORT);

    inet_ntoa_r(saddr.sin_addr.s_addr, addrbuf, sizeof(addrbuf) - 1);
    ESP_LOGI(TAG, "Binding to interface %s...", addrbuf);
    err = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
    if (err < 0)
    {
        ESP_LOGE(V4TAG, "Failed to bind socket. Error %d", errno);
        goto err;
    }

    // Assign multicast TTL (set separately from normal interface TTL)
    uint8_t ttl = MULTICAST_TTL;
    setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(uint8_t));
    if (err < 0)
    {
        ESP_LOGE(V4TAG, "Failed to set IP_MULTICAST_TTL. Error %d", errno);
        goto err;
    }

    // All set, socket is configured for sending
    return sock;

err:
    close(sock);
    return -1;
}
于 2020-09-10T01:18:46.303 回答