getnameinfo指定socklen_t

发布于 2024-08-30 22:26:29 字数 775 浏览 4 评论 0原文

getnameinfo 原型的第二个参数要求 socklen_t 类型,但 sizeof 使用 size_t。那么我怎样才能得到 socklen_t 呢?

原型:

int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
       char *restrict node, socklen_t nodelen, char *restrict service,
       socklen_t servicelen, int flags);

示例:

struct sockaddr_in SIN;
memset(&SIN, 0, sizeof(SIN)); // This should also be socklen_t ?
SIN.sin_family      = AF_INET;
SIN.sin_addr.s_addr = inet_addr(IP);
SIN.sin_port        = 0;

getnameinfo((struct sockaddr *)&SIN, sizeof(SIN) /* socklen_t */, BUFFER, NI_MAXHOST, NULL, 0, 0);

这将给出编译器错误:

socklen_t VAR;
getnameinfo((struct sockaddr *)&SIN, &VAR, BUFFER, NI_MAXHOST, NULL, 0, 0);

The 2nd arg for the getnameinfo prototype asks for a socklen_t type but sizeof uses size_t. So how can I get socklen_t ?

Prototype:

int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
       char *restrict node, socklen_t nodelen, char *restrict service,
       socklen_t servicelen, int flags);

Example:

struct sockaddr_in SIN;
memset(&SIN, 0, sizeof(SIN)); // This should also be socklen_t ?
SIN.sin_family      = AF_INET;
SIN.sin_addr.s_addr = inet_addr(IP);
SIN.sin_port        = 0;

getnameinfo((struct sockaddr *)&SIN, sizeof(SIN) /* socklen_t */, BUFFER, NI_MAXHOST, NULL, 0, 0);

This will give compiler error:

socklen_t VAR;
getnameinfo((struct sockaddr *)&SIN, &VAR, BUFFER, NI_MAXHOST, NULL, 0, 0);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

忱杏 2024-09-06 22:26:29

size_t 定义为无符号整数类型; C99保证至少是16位。

socklen_t 定义为积分至少 32 位的类型。 (编辑:它不一定是无符号的,尽管实际上负长度是没有意义的。)

因此,传递 size_t 参数并让编译器隐式将其转换为socklen_t,我认为它使您的代码更清晰,让隐式转换发生而不是添加迂腐的强制转换。

您的最后

socklen_t VAR;
getnameinfo((struct sockaddr *)&SIN, &VAR, BUFFER, NI_MAXHOST, NULL, 0, 0);

一个示例给出了编译器错误,因为您传递的是指向 a-socken_t 而不是 socklen_t 的指针。

size_t is defined as an unsigned integral type; C99 guarantees that it is at least 16 bits.

socklen_t is defined as an integral type of at least 32 bits. (Edit: It's not necessarily unsigned, although in practice a negative length would be meaningless.)

So there's no problem with passing a size_t parameter and letting the compiler implicitly cast it to socklen_t, and I would argue that it makes your code clearer to let the implicit conversion occur instead of adding pedantic casts.

Your final example

socklen_t VAR;
getnameinfo((struct sockaddr *)&SIN, &VAR, BUFFER, NI_MAXHOST, NULL, 0, 0);

gives a compiler error because you're passing a pointer-to-a-socken_t instead of a socklen_t.

趁年轻赶紧闹 2024-09-06 22:26:29

(这实际上是 这个恕我直言,错误地重复标记了问题,试图深入了解 socklen_t 的存在。)

正如其他人指出的那样,它可以被认为是 size_t< /code> 相当于 POSIX Sockets API,表示各种数据结构的长度(以字节为单位)。它在 bind()listen()connect() 函数中最为显着,其中它表示 的各种实现的长度。 code>struct sockaddr 但它根本不限于此。

POSIX 规范实际上解释了它的过去和现在的样子恕我直言,非常有启发性:

类型 socklen_t 的发明是为了涵盖该领域的各种实现。 socklen_t 的目的是成为自然限制大小的所有长度的类型;也就是说,它们是缓冲区的长度,不能明显地变得很大:例如网络地址、主机名、它们的字符串表示、辅助数据、控制消息和套接字选项。真正无限的大小由 size_t 表示,如 read()write() 等。

所有 socklen_t 类型最初(在 BSD UNIX 中)都是 int 类型。在 POSIX.1-2008 的开发过程中,决定将所有缓冲区长度更改为 size_t,这从表面上看是有意义的。当双模式 32/64 位系统出现时,这种选择不必要地使系统接口变得复杂,因为在 ILP32 和 LP64 模型下 size_t(长)的大小不同。除非某些实现已经提供了仅限 64 位的接口,否则可能会恢复到 int。折衷方案是一种可以通过实现定义为任意大小的类型:socklen_t

(This is rather an answer to this IMHO falsely duplicate-tagged question that tries to get to the bottom of socklen_t's existence.)

As others have pointed out it can be thought of as the size_t equivalent of the POSIX Sockets API that represents the length of various data structures in bytes. It is most notable in the bind(), listen(), connect() functions where it denotes the length of the various implementations of struct sockaddr but it is not limited to that at all.

The POSIX specification actually explains how it became to be and is very instructive IMHO:

The type socklen_t was invented to cover the range of implementations seen in the field. The intent of socklen_t is to be the type for all lengths that are naturally bounded in size; that is, that they are the length of a buffer which cannot sensibly become of massive size: network addresses, host names, string representations of these, ancillary data, control messages, and socket options are examples. Truly boundless sizes are represented by size_t as in read(), write(), and so on.

All socklen_t types were originally (in BSD UNIX) of type int. During the development of POSIX.1-2008, it was decided to change all buffer lengths to size_t, which appears at face value to make sense. When dual mode 32/64-bit systems came along, this choice unnecessarily complicated system interfaces because size_t (with long) was a different size under ILP32 and LP64 models. Reverting to int would have happened except that some implementations had already shipped 64-bit-only interfaces. The compromise was a type which could be defined to be any size by the implementation: socklen_t.

终弃我 2024-09-06 22:26:29

您的信息已过时, socklen_t 是至少 32 位的整数类型(不一定是无符号)(http://www.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html)。

Your information are out of date, socklen_t is an integer type (not necesarily unsigned) of at least 32 bits (http://www.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文