getnameinfo指定socklen\u t
getnameinfo原型的第二个参数要求使用socklen\u t类型,但sizeof使用size\u t。那我怎么才能拿到袜子呢 原型:getnameinfo指定socklen\u t,c,linux,networking,posix,socklen-t,C,Linux,Networking,Posix,Socklen T,getnameinfo原型的第二个参数要求使用socklen\u t类型,但sizeof使用size\u 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)
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\u t
作为无符号整数类型;C99保证它至少是16位
socklen\u t
作为至少32位的整数类型。(编辑:它不一定是无符号的,尽管在实践中,负长度是没有意义的。)
因此,传递size\u t
参数并让编译器隐式地将其强制转换为socklen\u t
是没有问题的,我认为让隐式转换发生而不是添加迂腐的强制转换会使代码更清晰
最后一个例子
socklen_t VAR;
getnameinfo((struct sockaddr *)&SIN, &VAR, BUFFER, NI_MAXHOST, NULL, 0, 0);
给出一个编译器错误,因为您传递的是指向socken\u t而不是socklen\u t的指针。您的信息已过期,socklen\u t是至少32位的整数类型(不一定是无符号的)() (这是一个试图弄清
socklen\t
存在的根本原因的答案。)
正如其他人所指出的,它可以被认为是posixsocketsapi的size\t
等价物,它以字节表示各种数据结构的长度。最值得注意的是bind()
,listen()
,connect()
函数,其中它表示struct sockaddr
的各种实现的长度,但并不限于此
这本书实际上解释了它是如何形成的,并且对IMHO很有启发性:
socklen\u t类型的发明是为了涵盖该领域中的各种实现。socklen\u t
的目的是成为所有长度的类型,这些长度在尺寸上自然有界;也就是说,它们是一个缓冲区的长度,而缓冲区的大小不能明显地变大:例如网络地址、主机名、它们的字符串表示、辅助数据、控制消息和套接字选项。真正无限的大小由size\t
表示,如read()
、write()
等
所有socklen\u t
类型最初(在BSD UNIX中)都是int
类型。在POSIX.1-2008的开发过程中,决定将所有缓冲区长度更改为size\u t
,这从表面上看是合理的。当出现双模式32/64位系统时,这种选择不必要地使系统接口复杂化,因为在ILP32和LP64型号下,size\u t
(带long)的大小不同。恢复到int
可能会发生,除非某些实现已经提供了仅64位的接口。折衷是一种可以通过实现定义为任意大小的类型:socklen\u t
sizeof
本身是否会导致问题?您是否遇到编译错误?没有问题或编译器错误,但我想如果getnameinfo要求socklen\t,我不应该通过size\t…生活中还有更糟糕的事情需要担心。我从来没有见过套接字代码会为此烦恼。我总是提供原型要求的东西。最佳实践。更重要的是,对于任何sockaddr
类型结构,sizeof
返回的值将始终适合socklen\t
类型,因此转换是安全的。