BIND - Linux手册页
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/。