|
bind() 函数在 /usr/include/sys/socket.h 中是这样定义的: /* Give the socket FD the local address ADDR (which is LEN bytes long). */
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
看一下__SOCK_SOCKADDR_ARG 的定义(同样在 /usr/include/sys/socket.h 里):
# define __CONST_SOCKADDR_ARG __const struct sockaddr *
跟踪再看一下 strcut sockaddr 是怎么定义的,这个定义在 /usr/include/bits/socket.h 里
/* Structure describing a generic socket address. */
struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[14]; /* Address data. */
};
由上可见,sockaddr 结构体的第一个成员是一个宏定义,再来看一下这个宏定义(在 /usr/include/bits/sockaddr.h 里):
/* This macro is used to declare the initial common members
of the data types used for socket addresses, `struct sockaddr',
`struct sockaddr_in', `struct sockaddr_un', etc. */
#define __SOCKADDR_COMMON(sa_prefix) sa_family_t sa_prefix##family
由注释可知,利用这个宏,我们根据需要,在 sockaddr 里可以填入不同的地址类型规范,如 struct sockaddr ,struct sockaddr_in,struct sockaddr_un 等。
同样在 /usr/include/bits/sockaddr.h 里看到上面的 sa_family_t 的原型是:
/* POSIX.1g specifies this type name for the `sa_family' member. */
typedef unsigned short int sa_family_t; 由此可见,是个无符号短整型。
例如,我们用的是 UNIX 域套接字,那么可以在 /usr/include/sys/un.h 中观察到 sockaddr_un 的定义:
/* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket. */
struct sockaddr_un
{
__SOCKADDR_COMMON (sun_);
char sun_path[108]; /* Path name. */
};
那么,根据上面的 __SOCKADDR_COMMON 的定义,可知结构体中的第一个成员为:
sun_family /* 两个 # 号表示简单相连*/
所以,这个结构体可改写为:
[/table][table=100%,#f7f7f7]sockaddr_un |
{
sa_family_t sun_family ;
char sun_path[108]; /* Path name. */
};
由于 sa_family 是无符号整型,而在 /usr/include/bits/socket.h 里定义的协议类型 (PF_XXX (实际上被重定义为 AF_XXX) 便可以赋给 sun_family,如 selfdefine_address.sun_family = AF_UNIX (表示使用 UNIX 域套接字)。 |
|