getsockname返回异常

Viewed 30

重现步骤


getsockname是否也需要在内核通过自定义dev来获取啊?

static int _eXosip_default_gateway_ipv4(char* destination, char* address, int size)
{
    socklen_t          len;
    int                sock_rt, on = 1;
    struct sockaddr_in iface_out;
    struct sockaddr_in remote;
    int                type;

    printf("\n------ [DEBUG] Start _eXosip_default_gateway_ipv4 ------\n");
    printf("[DEBUG] Input: destination=%s, address=%p, size=%d\n", destination ? destination : "NULL", address, size);

    // Step 1: 初始化目标地址结构体
    memset(&remote, 0, sizeof(struct sockaddr_in));
    remote.sin_family      = AF_INET;
    remote.sin_addr.s_addr = inet_addr(destination);
    remote.sin_port        = htons(11111);
    printf("[DEBUG] Remote address set: family=AF_INET, addr=%s, port=11111\n", inet_ntoa(remote.sin_addr));

    // Step 2: 创建 UDP 套接字
    memset(&iface_out, 0, sizeof(iface_out));
    type = SOCK_DGRAM;
#if defined(SOCK_CLOEXEC)
    type = SOCK_CLOEXEC | SOCK_DGRAM;
#endif
    sock_rt = socket(AF_INET, type, 0);
    printf("[DEBUG] socket() called: AF_INET, type=%d, protocol=0\n", type);
    if (sock_rt == -1) {
        printf("[ERROR] socket() failed! errno=%d (%s)\n", errno, strerror(errno));
        snprintf(address, size, "127.0.0.1");
        return OSIP_NO_NETWORK;
    }
    printf("[DEBUG] socket() returned fd=%d\n", sock_rt);

    // Step 3: 设置 SO_BROADCAST 选项
    if (setsockopt(sock_rt, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1) {
        printf("[ERROR] setsockopt(SO_BROADCAST) failed! errno=%d (%s)\n", errno, strerror(errno));
        _eXosip_closesocket(sock_rt);
        snprintf(address, size, "127.0.0.1");
        return OSIP_NO_NETWORK;
    }
    printf("[DEBUG] setsockopt(SO_BROADCAST) success\n");

    // Step 4: 连接目标地址(模拟路由选择)
    printf("[DEBUG] Attempting connect() to %s:11111...\n", inet_ntoa(remote.sin_addr));
    if (connect(sock_rt, (struct sockaddr*)&remote, sizeof(struct sockaddr_in)) == -1) {
        printf("[ERROR] connect() failed! errno=%d (%s)\n", errno, strerror(errno));
        _eXosip_closesocket(sock_rt);
        snprintf(address, size, "127.0.0.1");
        return OSIP_NO_NETWORK;
    }
    printf("[DEBUG] connect() success (UDP pseudo-connection established)\n");

    // Step 5: 获取本地绑定地址(出口 IP)
    len = sizeof(iface_out);
    printf("[DEBUG] Calling getsockname()...\n");
    if (getsockname(sock_rt, (struct sockaddr*)&iface_out, &len) == -1) {
        printf("[ERROR] getsockname() failed! errno=%d (%s)\n", errno, strerror(errno));
        _eXosip_closesocket(sock_rt);
        snprintf(address, size, "127.0.0.1");
        return OSIP_NO_NETWORK;
    }
    printf("[DEBUG] getsockname() returned: family=%d, addr=%s, port=%d\n", iface_out.sin_family,
           inet_ntoa(iface_out.sin_addr), ntohs(iface_out.sin_port));
    // iface_out.sin_addr.

    // Step 6: 关闭套接字
    _eXosip_closesocket(sock_rt);
    printf("[DEBUG] Socket closed (fd=%d)\n", sock_rt);

    // Step 7: 验证获取的 IP 是否有效
    if (iface_out.sin_addr.s_addr == 0) {
        printf("[WARN] getsockname() returned 0.0.0.0! No valid route to destination?\n");
        snprintf(address, size, "127.0.0.1");
        return OSIP_NO_NETWORK;
    }

    // Step 8: 返回结果
    printf("[DEBUG] Final local interface IP: %s\n", inet_ntoa(iface_out.sin_addr));
    osip_strncpy(address, inet_ntoa(iface_out.sin_addr), size - 1);
    printf("------ [DEBUG] End _eXosip_default_gateway_ipv4 (SUCCESS) ------\n\n");
    return OSIP_SUCCESS;
}

期待结果和实际结果

软硬件版本信息

错误日志


------ [DEBUG] Start _eXosip_default_gateway_ipv4 ------
[DEBUG] Input: destination=217.12.3.11, address=0x100a5cb20, size=128
[DEBUG] Remote address set: family=AF_INET, addr=217.12.3.11, port=11111
[DEBUG] socket() called: AF_INET, type=524290, protocol=0
[DEBUG] socket() returned fd=27
[DEBUG] setsockopt(SO_BROADCAST) success
[DEBUG] Attempting connect() to 217.12.3.11:11111...
[DEBUG] connect() success (UDP pseudo-connection established)
[DEBUG] Calling getsockname()...
[DEBUG] getsockname() returned: family=2, addr=0.0.0.0, port=49158
[DEBUG] Socket closed (fd=113246210)
[WARN] getsockname() returned 0.0.0.0! No valid route to destination?
[E/sal.skt] not find network interface device by protocol family(16).
[E/sal.skt] SAL socket protocol family input failed, return error -3.

尝试解决过程

补充材料

3 Answers

image.png
你好,我用4G网卡测试也是正确的。

好的 我先尝试拉取最新的代码试试看能不能解决这个问题

CC poly1305.c
Gen psa_crypto_driver_wrappers.h psa_crypto_driver_wrappers_no_static.c
Traceback (most recent call last):
File "../scripts/generate_driver_wrappers.py", line 18, in
import jsonschema
ModuleNotFoundError: No module named 'jsonschema'
make[5]: *** [Makefile:388:psa_crypto_driver_wrappers.h] 错误 1
make[4]: *** [Makefile:52:mbedtls_library] 错误 2
make[3]: *** [Makefile:13:all] 错误 2
make[2]: *** [Makefile:8:all] 错误 2
make[1]: *** [Makefile:73:libs] 错误 2
make: *** [Makefile:87:rtsmart] 错误 2
moon@ubuntu:~/rtos_k230_01kj$

你好 最新的代码编译不了了

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

void print_socket_info(const char *name, int sockfd) {
    struct sockaddr_in addr;
    socklen_t len = sizeof(addr);
    
    if (strcmp(name, "getsockname") == 0) {
        if (getsockname(sockfd, (struct sockaddr*)&addr, &len) < 0) {
            perror("getsockname failed");
            return;
        }
        printf("Local endpoint (%s):\n", name);
    } else {
        if (getpeername(sockfd, (struct sockaddr*)&addr, &len) < 0) {
            perror("getpeername failed");
            return;
        }
        printf("Remote endpoint (%s):\n", name);
    }
    
    printf("  IP: %s\n", inet_ntoa(addr.sin_addr));
    printf("  Port: %d\n", ntohs(addr.sin_port));
    printf("  Family: %d\n", addr.sin_family);
}

int test_connection(const char *host, int port) {
    int sockfd;
    struct sockaddr_in server_addr;
    struct hostent *server;

    // Create socket
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket creation failed");
        return -1;
    }

    // Resolve hostname
    server = gethostbyname(host);
    if (server == NULL) {
        fprintf(stderr, "Error: No such host\n");
        close(sockfd);
        return -1;
    }

    // Set up server address
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    memcpy(&server_addr.sin_addr.s_addr, server->h_addr, server->h_length);
    server_addr.sin_port = htons(port);

    // Connect to remote server
    printf("Connecting to %s:%d...\n", host, port);
    if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("connect failed");
        close(sockfd);
        return -1;
    }
    printf("Connection established!\n\n");

    // Test getsockname (local address)
    print_socket_info("getsockname", sockfd);
    printf("\n");

    // Test getpeername (remote address)
    print_socket_info("getpeername", sockfd);

    close(sockfd);
    return 0;
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <host> <port>\n", argv[0]);
        fprintf(stderr, "Example: %s example.com 80\n", argv[0]);
        return 1;
    }

    const char *host = argv[1];
    int port = atoi(argv[2]);

    return test_connection(host, port);
}
msh />/data/helloworld baidu.com 80
Connecting to baidu.com:80...
Connection established!

Local endpoint (getsockname):
  IP: 192.168.123.68
  Port: 64025
  Family: 2

Remote endpoint (getpeername):
  IP: 110.242.68.66
  Port: 80
  Family: 2

你好,我这边测试是正常的哦。

我使用了你的代码进行测试 是不行的 可能是因为我的环境是4G网卡? 我将日志放在楼下了