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);
答案 0 :(得分:9)
size_t
is defined作为无符号整数类型; C99保证它至少为16位。
socklen_t
is defined作为至少32位的整数类型。 (编辑:它不一定是无符号的,但在实践中,负长度将毫无意义。)
所以传递一个size_t
参数并让编译器隐式地将它转换为socklen_t
没有问题,我认为这会让你的代码更清晰,让隐式转换发生而不是添加迂腐管型。
你的最后一个例子
socklen_t VAR;
getnameinfo((struct sockaddr *)&SIN, &VAR, BUFFER, NI_MAXHOST, NULL, 0, 0);
给出了一个编译器错误,因为你传递的指针指向socken_t而不是socklen_t。
答案 1 :(得分:1)
您的信息已过期,socklen_t是一个至少32位(http://www.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html)的整数类型(不一定是无符号)。
答案 2 :(得分:0)
(这是this IMHO falsely duplicate-tagged question试图触及socklen_t
存在底部的答案。)
正如其他人所指出的,可以将其视为POSIX套接字API的size_t
等价物,它表示各种数据结构的长度(以字节为单位)。最值得注意的是bind()
,listen()
,connect()
函数,它表示struct sockaddr
的各种实现的长度,但并不仅限于此。< / p>
POSIX specification实际上解释了它如何成为并且非常有启发性恕我直言:
类型
socklen_t
的发明是为了涵盖该领域的实现范围。socklen_t
的意图是所有长度自然有限的类型;也就是说,它们是一个缓冲区的长度,它不能合理地变成大尺寸:网络地址,主机名,这些的字符串表示,辅助数据,控制消息和套接字选项都是例子。真正的无限大小由size_t
表示,如read()
,write()
,依此类推。所有
socklen_t
类型最初(在BSD UNIX中)类型为int
。在开发POSIX.1-2008期间,决定将所有缓冲区长度更改为size_t
,这在面值处显示有意义。当双模式32/64位系统出现时,这种选择会不必要地使系统接口变得复杂,因为size_t
(带有long)在ILP32和LP64模型下的大小不同。恢复到int
会发生,除了一些实现已经发布了64位接口。妥协是一种类型,可以通过实现定义为任何大小:socklen_t
。