我正在研究 C 中的套接字编程,我很好奇为什么你必须在和之类的函数中传递一个参数和该参数的长度?为什么不只在函数内部使用?bind()
connect()
sizeof()
2 回答
因为它提供了一种简单的方法来使用相同的 API 处理许多不同类型的协议。
由于套接字可以使用许多不同的底层协议(正如@larsman 所指出的那样),因此调用无法确切地知道它正在处理哪种类型的结构。各种类型都有一些基本的“继承” struct sockaddr
。
此外,它提供了一些前向兼容性;针对库的一个版本编译的二进制文件可能会针对更高版本运行,其中地址类型可能已经增长(例如支持 IPv6)。
通过将调用者的大小想法传递给被调用函数,被调用函数可以注意不要覆盖内存。
我想你的第三个论点
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
你不能sizeof(addr)
在函数内部做,因为那只会返回指针的大小,而不是指向的结构。sizeof(struct sockaddr)
也不会起作用,因为不同的地址系列(本地套接字、IPv4、IPv6、外来网络协议)具有不同大小sockaddr
的类型。
例如,对于 IPv4 套接字,您调用
struct sockaddr_in my_addr;
// set up my_addr
bind(fd, (struct sockaddr *)my_addr, sizeof(struct sockaddr_in));
但是对于本地(Unix)域套接字,您传递的sockaddr_un
a 可能具有不同的长度。
[在我的 Linux 机器上,sizeof(struct sockaddr_in) == 16
但是sizeof(struct sockaddr_un) == 110
。]
如果您习惯于面向对象编程,那么您可以将sockaddr
族视为具有动态类型的(浅)类层次结构。struct sockaddr
是抽象基类,bind
,connect
等是方法。由于 C 没有内置的动态类型,因此必须对其进行模拟,并且传递结构的大小是其中的一部分。