• Linux之bind 函数(详细篇)


    bind作用及形式  

    - bind a name to a socket

    1. #include /* See NOTES */
    2. #include
    3. int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

    sockfd:        socket文件描述符 

    addr:            构造出IP地址 + 端口号

    addrlen:       sizeof(addr)长度

    返回值:         成功返回0,失败返回-1, 设置errno

    bind描述

    当使用socket创建套接字时,它存在于名称空间(地址族)中,但没有为其分配地址。 bind() 将 addr 指定的地址分配给文件描述符 sockfd 引用的socket。 addrlen 指定addr 指向的地址结构的大小(以字节为单位)。 传统上,此操作称为“为套接字分配名称”。

    sockaddr 和 sockaddr_in 结构定义如下:

    1. struct sockaddr {
    2. sa_family_t sa_family;
    3. char sa_data[14];
    4. }
    5. struct sockaddr_in {
    6. sa_family_t sin_family; /* address family: AF_INET */
    7. in_port_t sin_port; /* port in network byte order */
    8. struct in_addr sin_addr; /* internet address */
    9. };
    10. /* Internet address. */
    11. struct in_addr {
    12. uint32_t s_addr; /* address in network byte order */
    13. };

         服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接,因此服务器需要调用bind绑定一个固定的网络地址和端口号。

           bind()的作用是将参数sockfd和addr绑定在一起,使sockfd这个用于网络通讯的文件描述符监听addr所描述的地址和端口号。前面讲过,struct sockaddr *是一个通用指针类型,addr参数实际上可以接受多种协议的sockaddr结构体,而它们的长度各不相同,所以需要第三个参数addrlen指定结构体的长度。如:

    1. struct sockaddr_in servaddr;
    2. bzero(&servaddr, sizeof(servaddr));
    3. servaddr.sin_family = AF_INET;
    4. servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    5. servaddr.sin_port = htons(6666);

    首先将整个结构体清零,然后设置地址类型为AF_INET,网络地址为INADDR_ANY,这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个IP地址,这样设置可以在所有的IP地址上监听,直到与某个客户端建立了连接时才确定下来到底用哪个IP地址,端口号为6666。

    bind例子

    显示如何在 UNIX (AF_UNIX) 域中绑定流套接字并接受连接:

    1. //显示如何在 UNIX (AF_UNIX) 域中绑定流套接字并接受连接:
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define MY_SOCK_PATH "/somepath"
    8. #define LISTEN_BACKLOG 50
    9. #define handle_error(msg) \
    10. do { perror(msg); exit(EXIT_FAILURE); } while (0)
    11. int
    12. main(int argc, char *argv[])
    13. {
    14. int sfd, cfd;
    15. struct sockaddr_un my_addr, peer_addr;
    16. socklen_t peer_addr_size;
    17. sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    18. if (sfd == -1)
    19. handle_error("socket");
    20. memset(&my_addr, 0, sizeof(struct sockaddr_un));
    21. /* Clear structure */
    22. my_addr.sun_family = AF_UNIX;
    23. strncpy(my_addr.sun_path, MY_SOCK_PATH,
    24. sizeof(my_addr.sun_path) - 1);
    25. if (bind(sfd, (struct sockaddr *) &my_addr,
    26. sizeof(struct sockaddr_un)) == -1)
    27. handle_error("bind");
    28. if (listen(sfd, LISTEN_BACKLOG) == -1)
    29. handle_error("listen");
    30. /* Now we can accept incoming connections one
    31. at a time using accept(2) */
    32. peer_addr_size = sizeof(struct sockaddr_un);
    33. cfd = accept(sfd, (struct sockaddr *) &peer_addr,
    34. &peer_addr_size);
    35. if (cfd == -1)
    36. handle_error("accept");
    37. /* Code to deal with incoming connection(s)... */
    38. /* When no longer required, the socket pathname, MY_SOCK_PATH
    39. should be deleted using unlink(2) or remove(3) */
    40. }

  • 相关阅读:
    IIS 解析漏洞复现
    12 分布式锁加入看门狗
    【示波器专题】现代数字示波器的主要组成部分
    结构型设计模式- C++实现
    redis之单线程的redis都有哪些阻塞点
    visual-studio-code通过跳板机连接远程服务器的配置操作
    Javers 比较两个类的差异
    化工行业升级进行时,数商云B2B商城系统询报价功能助力企业精确对接供求
    MinIO (二) .net core中实现上传下载
    接口测试时遇到接口加密了该如何处理?
  • 原文地址:https://blog.csdn.net/weixin_45678463/article/details/132846971