【问题标题】:Why socklent_t * is used in accept() in socket programming?为什么 socklent_t * 在 socket 编程中的 accept() 中使用?
【发布时间】:2015-05-15 05:15:28
【问题描述】:

在 C 套接字编程中,accept() 声明如下所示:

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

我能理解sockfdstruct sockaddr *addr的用途。

但是为什么我们要传递套接字长度的地址,它本来可以是socklen_t。因为如果accept() 函数需要长度,那么它可以通过socklen_t 得到它。为什么函数的原型是这样声明的?

那么使用socklen_t *类型背后的原因是什么?

【问题讨论】:

  • socketlen_t 是一个 type,用于声明一个 variable 可以保存套接字地址的长度,该地址本身是可变的,具体取决于在地址族上。它本身不是那么长。

标签: c sockets networking


【解决方案1】:

在与它接受的套接字的地址/协议系列无关的代码中,它可能使用通用的sockaddr_storage 结构来保存结果。指向的socklen_t的初始值就是这个存储的大小; accept 返回后的值是结果对等地址的实际大小。此外,像AF_UNIX 这样的一些地址/协议族具有可变长度的地址,因此即使您知道类型,您也可能不知道大小。

【讨论】:

  • 所以这是长度,因为他们知道类型无法获得大小?
【解决方案2】:
  1. 为什么需要 addrlen

    accept 设计用于处理很多协议族,它们的 addr 结构可能长度不同。

参数 addr 是一个指向 sockaddr 结构的指针。这个结构填充了 对等套接字的地址,如通信层所知。确切的格式 返回的地址 addr 由套接字的地址族确定(参见 socket(2) 和相应的协议手册页)。 addr为NULL时,不填任何内容;在这 情况下,不使用addrlen,也应该为NULL。

  1. 为什么是指针

addrlen 参数是一个值结果参数:调用者必须初始化它以包含 addr 指向的结构的大小(以字节为单位);返回时它将包含 对等地址的实际大小。

  1. 为什么是 socklen_t

socklen_t 类型 accept() 的第三个参数最初被声明为一个 int * (并且是在 libc4 和 libc5 以及许多其他系统,如 4.x BSD、SunOS 4、SGI); POSIX.1g 草案 标准想把它改成 size_t *,这就是 SunOS 5 的样子。后来 POSIX 草案有 socklen_t *,Single UNIX Specification 和 glibc2 也有。报价- 林纳斯·托瓦兹:

"任何健全的库必须让“socklen_t”的大小与 int 相同。其他任何东西 破坏任何 BSD 套接字层的东西。 POSIX 最初确实将其设为 size_t,而我(和 希望其他人,但显然不是太多)确实非常大声地向他们抱怨。 使它成为 size_t 完全被破坏了,正是因为 size_t 很少是相同的 例如,在 64 位架构上,大小为“int”。它的大小必须与 “int”,因为这就是 BSD 套接字接口。无论如何,POSIX 人最终会—— 盟友得到了线索,并创建了“socklen_t”。他们不应该一开始就碰它 地方,但是一旦他们这样做了,他们就觉得它必须有一个命名的类型才能获得一些深不可测的理解。 儿子(可能有人不喜欢因为做了最初的愚蠢而丢脸 事情,所以他们默默地把他们的错误改名了)。”

ref: man accept, man socket

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 2020-05-27
    • 2022-07-05
    • 1970-01-01
    • 2011-10-07
    • 2015-08-21
    • 1970-01-01
    相关资源
    最近更新 更多