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
。