【发布时间】:2017-05-05 13:28:37
【问题描述】:
我开始在 C 中使用套接字,当我使用 bind() 系统调用将套接字绑定到地址时,我必须指定 addrlen 参数。
为什么套接字中需要地址长度?
【问题讨论】:
标签: c sockets system-calls
我开始在 C 中使用套接字,当我使用 bind() 系统调用将套接字绑定到地址时,我必须指定 addrlen 参数。
为什么套接字中需要地址长度?
【问题讨论】:
标签: c sockets system-calls
绑定函数 (syscall) 是通用函数,它必须处理多种类型的地址,IPv4、IPv6、蓝牙、unix 套接字和...每种地址类型的大小可能与其他地址类型不同,因此您必须制作它通过传递其大小来清除绑定您要传递的地址。
bind 是一个系统调用,系统调用只是一个包装函数,用于用户空间与内核空间交互。当您通过套接字系统调用创建套接字时,将在调用进程的文件描述符表中创建一条记录。记录本身包括套接字的类型。 当你调用 bind 并将地址传递给它时,地址应该被复制到内核空间,但是地址有多大?绑定系统调用不知道您要绑定的套接字,因为在内核空间和用户空间绑定函数中创建的套接字记录及其各自的系统调用不知道它需要的大小。实际上,绑定只是系统调用,它将地址数据复制到内核空间并通知内核。
另一方面,绑定无法在运行时确定地址时间,因为纯 C 中没有运行时类型检查。
所以此时绑定不知道地址,你应该指定地址大小,所以地址结构将完全复制到内核空间。
【讨论】:
有几种不同的套接字地址
这些都有自己的sockaddr_* 结构,即sockaddr_in 代表AF_INET,sockaddr_in6 代表AF_INET6,等等。
传递长度允许内核检查传递的数据是否与套接字类型一致。
【讨论】:
系统调用是独立于协议的,例如它们适用于
所有这些都可能有不同长度的套接字描述。这就是为什么你必须指定相应结构的长度。
【讨论】:
绑定(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr))
它需要三个参数,套接字文件描述符、绑定的地址和地址的大小被绑定
为什么套接字中需要地址长度?
这是一个限制
例如我会处理如下
if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{
error("ERROR on binding");
}
【讨论】: