我目前正在使用Esp32,除了wifi之外,它还具有以太网接口。 我正在使用 esp-idf v3.3 和 FreeRTOS。
为了使用它,我包含了"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(结构 netif * netif(,但我不知道这是否是选择要用于特定操作的接口的最佳方式(我应该从一个接换到另一个接口(
只需获取以太网接口的 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
然后使用它来绑定套接字,例如:
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;
}