getnameinfo指定socklen_t

Nee*_*ran 3 c linux networking posix 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);
Run Code Online (Sandbox Code Playgroud)

例:

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);
Run Code Online (Sandbox Code Playgroud)

这会给编译器错误:

socklen_t VAR;
getnameinfo((struct sockaddr *)&SIN, &VAR, BUFFER, NI_MAXHOST, NULL, 0, 0);
Run Code Online (Sandbox Code Playgroud)

Jos*_*ley 9

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);
Run Code Online (Sandbox Code Playgroud)

给出了一个编译器错误,因为你传递的指针指向socken_t而不是socklen_t.

  • 更重要的是,任何“sockaddr”类型结构的“sizeof”返回的值始终适合“socklen_t”类型,因此转换是安全的。 (2认同)