getnameinfo指定socklen_t

getnameinfo原型的第二个arg要求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); 

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); 

给出编译器错误,因为您传递的指针指向socken_t而不是socklen_t。

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

(这是对这个恕我直言,错误复制标记的问题的答案,试图找到socklen_t存在的底部。)

正如其他人所指出的,它可以被认为是POSIX套接字API的size_t等价物,它表示各种数据结构的长度(以字节为单位)。 它最值得注意的是bind()listen()connect()函数,它表示struct sockaddr的各种实现的长度,但它根本不限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 (带有long)的大小不同。 除了某些实现已经发布了64位接口之外,还会发生恢复到int 。 妥协是一种类型,可以通过实现定义为任何大小: socklen_t