C++ 为什么在套接字编程中需要值结果参数?(需要澄清)

C++ 为什么在套接字编程中需要值结果参数?(需要澄清),c++,c,sockets,parameter-passing,C++,C,Sockets,Parameter Passing,当被问到“什么是值结果参数,为什么在套接字编程中需要它?”这样的问题时,我有点困惑 尽管阅读了数不清的页面和其他问题,但我仍在努力完全理解什么是价值结果论证 我的理解是,在值结果参数中,内核能够对传递的参数进行更改(因为我们给它一个引用/指针,而不仅仅是它的值),并将它返回给调用它的进程/函数。它既是调用函数时的一个“值”(例如,告诉内核结构的大小,这样它就不会写太多),也是函数返回时的一个结果(我们在结构中实际写了多少) 我很难回答的是,为什么这在Socket编程中如此重要?特别是,当我们处理

当被问到“什么是值结果参数,为什么在套接字编程中需要它?”这样的问题时,我有点困惑

尽管阅读了数不清的页面和其他问题,但我仍在努力完全理解什么是价值结果论证

我的理解是,在值结果参数中,内核能够对传递的参数进行更改(因为我们给它一个引用/指针,而不仅仅是它的值),并将它返回给调用它的进程/函数。它既是调用函数时的一个“值”(例如,告诉内核结构的大小,这样它就不会写太多),也是函数返回时的一个结果(我们在结构中实际写了多少)

我很难回答的是,为什么这在Socket编程中如此重要?特别是,当我们处理
sockaddr
结构并传递它们的引用和大小时,即
accept()


我意识到这个问题可能听起来有点傻,但对此的任何澄清都会很好,所以请提前感谢

您正确理解了什么是值结果参数。将输入值指定给变量并通过引用传递,以便函数可以使用输出值修改变量。这样就不必为输出传递单独的参数,也不必更改函数返回值的语义

sockaddr
参数需要这样做的原因是,不同的传输实现不同的
sockaddr\u…
结构,它们具有不同的大小和布局(
sockaddr\u in
对于IPv4,
sockaddr\u in 6
对于IPv6,
sockaddr\u un
对于UNIX域套接字,等等)。大多数平台还提供了
sockaddr\u存储
结构的实现,该结构足够大,可以容纳所有其他
sockaddr\u…
结构,在编写多传输代码时非常有用

因此,在
accept()
的情况下,您必须传入将接收客户端的
sockaddr\u…
的缓冲区的完整大小。当新客户机到达时,
accept()
将验证缓冲区是否足够大,以便在填充缓冲区之前接收客户机的实际
sockaddr\u…
数据,并返回实际填充的缓冲区数量

例如,如果您知道该套接字仅支持IPv4(创建为
AF_INET
-系列套接字),那么您可以使用
sockaddr_in
作为缓冲区,使用
sizeof(sockaddr_in)
作为缓冲区大小,或者使用
sockaddr_存储
作为缓冲区,使用
sizeof(sockaddr_存储)
作为缓冲区大小。在任何一种情况下,
accept()
都将在中使用
sockaddr\u填充缓冲区,并将缓冲区大小返回为
sizeof(sockaddr\u In)
。与仅限IPv6的套接字(创建为
AF\u INET6
-系列套接字)相同,只需使用
sockaddr\u in6


现在,让我们假设您有一个同时支持IPv4和IPv6的双栈套接字(禁用了
AF\u INET6
-仅限IPv6
选项的系列套接字)。您可以使用
sockaddr\u存储
作为缓冲区,使用
sizeof(sockaddr\u存储)
作为缓冲区大小,
accept()
将使用
sockaddr\u in
sockaddr\u in 6
填充缓冲区,并返回适当的缓冲区大小,具体取决于是否接受IPv4或IPv6客户端。然后,您可以读取
sockaddr\u存储的
ss\u系列
字段,并将数据强制转换为
sockaddr\u in
中的
AF\u INET
sockaddr\u in 6
中的
AF\u INET6

问题有点奇怪-我不明白为什么需要这些参数-以及“socket编程”这是一个相当宽泛的术语。你有没有考虑过问那些问你这些问题的人这些问题是什么意思?唉,目前还没有。例如,accept()方法是value result,我应该将其添加到中。我找到了另一个线程,可以回答您的问题。请有人关闭复制:非常感谢,这是非常有意义的!特别是在使用适当的协议结构填充缓冲区时,支持IPv4和V6。非常感谢:)