• LInux Socket绑定网卡和IP


    #include <errno.h> // errno
    #include <sys/socket.h> // socket
    #include <string.h> // strerror
    #include <unistd.h> // close

    #define LOG_TAG "[exam1_socket_bind]"

    static void sock_create_bind(void);
    static int32_t socket_set_eth_interface_and_ip_addr(const char *eth_interface, const char *ip_addr);

    // 通过ifconfig查看网口、ip;(ens33: inet 192.168.54.231)
    void exam1_socket_bind_test(void)
    {
    VOID_FUNC_ENTER();
    // eth interface or ip addr, can set NULL.
    socket_set_eth_interface_and_ip_addr("ens33", "192.168.54.231");
    sock_create_bind();
    VOID_FUNC_EXIT();
    }

    // ip addr
    #include <netinet/in.h>
    static uint8_t g_socket_ip_flag = 0;
    struct sockaddr_in g_socket_serv_addr;
    // eth interface
    #include <net/if.h> // ifreq
    #include <arpa/inet.h> // inet_addr
    #define SOCKET_IFNAME_MAX_LEN (16)
    static uint8_t g_socket_ifname_flag = 0;
    static char g_socket_ifname[SOCKET_IFNAME_MAX_LEN] = { 0 };
    static uint8_t g_socket_ifname_len = 0;

    static int32_t socket_set_eth_interface_and_ip_addr(const char *eth_interface, const char *ip_addr)
    {
    int32_t ret = 0;
    do {

    if (eth_interface != NULL) {
    LOGD("socket ifname=%s, len=%d", eth_interface, (int32_t)strlen(eth_interface));
    memset(g_socket_ifname, 0, SOCKET_IFNAME_MAX_LEN);
    memmove((char *)g_socket_ifname, eth_interface, strlen(eth_interface)+1);
    g_socket_ifname_len = strlen(eth_interface)+1;
    g_socket_ifname_flag = 1;
    }

    if (ip_addr != NULL) {
    LOGD("socket ip_addr=%s, len=%d", ip_addr, (int32_t)strlen(ip_addr));
    memset(&g_socket_serv_addr, 0, sizeof(g_socket_serv_addr));
    g_socket_serv_addr.sin_family = AF_INET;
    /* INADDR_ANY表示不管是哪个网卡接收到数据,只要目的端口是SERV_PORT,就会被该应用程序接收到 */
    //g_socket_serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    g_socket_serv_addr.sin_addr.s_addr = inet_addr(ip_addr);
    // g_socket_serv_addr.sin_port = htons(8080);
    g_socket_serv_addr.sin_port = 0;
    g_socket_ip_flag = 1;
    }

    } while (0);

    return ret;
    }


    /*
    * Create a socket handler.
    *
    * @return:
    * >= 0: succeeds, identifier of the socket handler;
    * -1: failed;
    */
    static void sock_create_bind(void)
    {
    int32_t sock = 0;

    do {
    // sock = socket(AF_INET, SOCK_STREAM, 0);
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
    LOGE("socket fail, errno=%s", strerror(errno));
    break;
    } else {
    LOGI("socket create success, sock=%d", sock);
    }

    LOGD("socket=%d, ifname flag=%d", sock, g_socket_ifname_flag);
    if (g_socket_ifname_flag == 1) {
    LOGD("socket ifname=%s", g_socket_ifname);
    struct ifreq interface;
    strncpy(interface.ifr_ifrn.ifrn_name, g_socket_ifname, g_socket_ifname_len);
    if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) {
    LOGE("setsockopt failed, errno=%s", strerror(errno));
    } else {
    LOGD("setsockopt(%s) success", g_socket_ifname);
    }
    }

    LOGD("socket=%d, ip flag=%d", sock, g_socket_ip_flag);
    if (g_socket_ip_flag == 1) {
    if (bind(sock, (struct sockaddr *)&g_socket_serv_addr, sizeof(g_socket_serv_addr)) == -1) {
    LOGE("bind ip failed, errno=%s", strerror(errno));
    } else {
    LOGD("bind ip success");
    }
    }
    } while (0);

    // only test, close sock
    if (sock > 0) {
    LOGI("only test, close sock(%d)", sock);
    (void)close(sock);
    sock = -1;
    }
    }

    /*
    参考资料:

    socket 绑定网口
    Linux 套接字编程 套接字选项SO_BINDTODEVICE 绑定接口 示例
    https://blog.csdn.net/fuyuande/article/details/82728734
    linux下socket指定网卡
    https://blog.csdn.net/weixin_42525261/article/details/116681809
    Linux的SOCKET编程详解:
    https://www.cnblogs.com/zhaobin-diray/p/9073298.html
    socket 绑定ip
    linux之socket相关的函数结构体解析
    https://blog.csdn.net/weixin_37921201/article/details/90107919
    Socket Server指定监听端口和IP
    https://blog.csdn.net/qq_34039018/article/details/101026332
    socket 通信关于bind IP地址
    https://blog.csdn.net/beilingshan/article/details/72821076

    Linux多播问题(No such device)解决方法
    https://zhuanlan.zhihu.com/p/291203312

  • 相关阅读:
    坚持--从今天开始
    51系列单片机的精确延时的解释(文章如有问题之处,请劳烦指正,谢谢!) 可以看看采纳下。
    利用宏定义实现C++程序在Unix和Win32环境下的通用性
    [转]浅谈C++指针直接调用类成员函数
    类间调用inline函数的效率
    C++ inline函数与编译器设置
    GNU的makefile文件编写说明
    Windows Live Writer 2012 Test
    测试Windows Live Writer
    Mathematica学习笔记2
  • 原文地址:https://www.cnblogs.com/zwh0214/p/15348546.html
Copyright © 2020-2023  润新知