BIND - Linux手册页

时间:2019-08-20 17:58:35  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2020-06-09

名称

bind-将名称绑定到套接字

语法

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr,
         socklen_t addrlen);

说明

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

通常,在SOCK_STREAM套接字接收连接之前,必须使用bind()分配本地地址(请参见accept(2))。

名称绑定中使用的规则在地址族之间有所不同。有关详细信息,请查阅第7节中的手册条目。对于AF_INET,请参见ip(7);。对于AF_INET6,请参见ipv6(7);对于AF_UNIX,请参见unix(7);。对于AF_APPLETALK,请参阅ddp(7);对于AF_PACKET,请参见packet(7);对于AF_X25,请参见x25(7);对于AF_NETLINK,请参见netlink(7)。

为addr参数传递的实际结构将取决于地址族。 sockaddr结构的定义如下:

struct sockaddr {
    sa_family_t sa_family;
    char        sa_data[14];
}

该结构的唯一目的是强制转换在addr中传递的结构指针,以避免编译器警告。请参阅下面的示例。

返回值

成功时,返回零。如果出错,则返回-1,并正确设置errno。

错误说明

EACCES
该地址受保护,并且该用户不是超级用户。
EADDRINUSE
给定的地址已被使用。
EADDRINUSE
(Internet域套接字)在套接字地址结构中将端口号指定为零,但是在尝试绑定到临时端口时,确定当前正在使用临时端口范围内的所有端口号。请参阅/ proc / sys / net / ipv4 / ip_local_port_range ip(7)的讨论。
EBADF
sockfd不是有效的文件描述符。
EINVAL
套接字已绑定到一个地址。
EINVAL
addrlen错误,或者addr不是此套接字域的有效地址。
ENOTSOCK
文件描述符sockfd不引用套接字。

以下错误特定于UNIX域(AF_UNIX)套接字:

EACCES
在路径前缀的组件上拒绝搜索许可。 (另请参见path_resolution(7)。)
EADDRNOTAVAIL
请求的接口不存在,或者请求的地址不是本地地址。
EFAULT
addr指向用户可访问的地址空间之外。
ELOOP
解决addr时遇到太多符号链接。
ENAMETOOLONG
地址太长。
ENOENT
套接字路径名的目录前缀中的组件不存在。
ENOMEM
内核内存不足。
ENOTDIR
路径前缀的组成部分不是目录。
EROFS
套接字索引节点将驻留在只读文件系统上。

遵循规范

POSIX.1-2001,POSIX.1-2008,SVr4、4.4BSD(bind()首次出现在4.2BSD中)。

备注

POSIX.1不需要包含,并且在Linux上不需要此头文件。但是,某些历史(BSD)实现需要此头文件,而可移植的应用程序最好将其包括在内。

有关socklen_t类型的背景,请参见accept(2)。

BUGS

没有介绍透明代理选项。

示例

getaddrinfo(3)中可以找到将bind()与Internet域套接字一起使用的示例。

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

#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MY_SOCK_PATH "/somepath"
#define LISTEN_BACKLOG 50

#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)

int
main(int argc, char *argv[])
{
    int sfd, cfd;
    struct sockaddr_un my_addr, peer_addr;
    socklen_t peer_addr_size;

    sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1)
        handle_error("socket");

    memset(&my_addr, 0, sizeof(struct sockaddr_un));
                        /* Clear structure */
    my_addr.sun_family = AF_UNIX;
    strncpy(my_addr.sun_path, MY_SOCK_PATH,
            sizeof(my_addr.sun_path) - 1);

    if (bind(sfd, (struct sockaddr *) &my_addr,
            sizeof(struct sockaddr_un)) == -1)
        handle_error("bind");

    if (listen(sfd, LISTEN_BACKLOG) == -1)
        handle_error("listen");

    /* Now we can accept incoming connections one
       at a time using accept(2) */

    peer_addr_size = sizeof(struct sockaddr_un);
    cfd = accept(sfd, (struct sockaddr *) &peer_addr,
                 &peer_addr_size);
    if (cfd == -1)
        handle_error("accept");

    /* Code to deal with incoming connection(s)... */

    /* When no longer required, the socket pathname, MY_SOCK_PATH
       should be deleted using unlink(2) or remove(3) */
}

另外参见

accept(2),connect(2),getsockname(2),listen(2),socket(2),getaddrinfo(3),getifaddrs(3),ip(7),ipv6(7),path_resolution(7),套接字(7),unix(7)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/