linux手册翻译——bind(2)
bind - bind a name to a socket
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
当用socket(2) 创建套接字时,仅仅为其分配了空间但是没有指定地址。bind()将addr
指向的地址分配给文件描述符sockfd
引用的套接字。addrlen
指定 addr
指向的地址结构的大小(以字节为单位)。传统上,此操作称为“为套接字分配名称”。
我对bind的理解:只有被绑定的IP地址,才能访问到此socket。若绑定了0.0.0.0,则可以接收任意地址的连接,若绑定了127.0.0.1,则只能接收本地的连接。
在 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
The address is protected, and the user is not the superuser. -
EADDRINUSE
The given address is already in use. -
EADDRINUSE
(Internet domain sockets) The port number was specified aszero in the socket address structure, but, upon attempting to bind to an ephemeral port, it was determined that allport numbers in the ephemeral port range are currently inuse. See the discussion of/proc/sys/net/ipv4/ip_local_port_range ip(7). -
EBADF
sockfd is not a valid file descriptor. -
EINVAL
The socket is already bound to an address. -
EINVAL
addrlen is wrong, or addr is not a valid address for this socket's domain. -
ENOTSOCK
The file descriptor sockfd does not refer to a socket.
The following errors are specific to UNIX domain (AF_UNIX) sockets: -
EACCES
Search permission is denied on a component of the path prefix. (See also path_resolution(7).) -
EADDRNOTAVAIL
A nonexistent interface was requested or the requested address was not local. -
EFAULT
addr points outside the user's accessible address space. -
ELOOP
Too many symbolic links were encountered in resolving addr. -
ENAMETOOLONG
addr is too long. -
ENOENT
A component in the directory prefix of the socket pathname does not exist. -
ENOMEM
Insufficient kernel memory was available. -
ENOTDIR
A component of the path prefix is not a directory. -
EROFS
The socket inode would reside on a read-only filesystem.
POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD (bind() first appeared in 4.2BSD).
有关 socklen_t 类型的背景信息,请参阅 accept(2)。
The transparent proxy options are not described.
在 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(my_addr));
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(my_addr)) == -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(peer_addr);
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). */
}