如果是 IPv6,accept() 函数返回 -1

发布于 2024-11-14 09:23:37 字数 154 浏览 1 评论 0原文

在我的程序中,我试图实现对双栈操作(IPv4 和 IPv6 套接字)的支持。

对于 IPv4,一切工作正常。但在 IPv6 情况下,accept() 返回 -1 值(错误)。

谁能提出可能的原因以及如何解决它?

In my program, I am trying to implement support for dual-stack operation (both IPv4 and IPv6 sockets).

In the case of IPv4, everything is working fine. But in the IPv6 case, accept() is returning a -1 value (an error).

Can anyone suggest the possible reasons, and how to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

も星光 2024-11-21 09:23:37

accept()返回-1时,errno将被设置以指示发生了什么具体错误。请致电 perror("accept") 以简单方式查看错误所在,并使用结果更新您的问题。

另请注意,必须在以下套接字上调用 accept()

  • 使用 socket() 调用创建。 (您应该传递 PF_INET6 作为套接字的第一个参数来创建 IPv6 协议族套接字)
  • 绑定,使用 bind() 使用 struct sockaddr_in6 > 参数作为第二个参数(对于 IPv6,其 sin6_family 设置为 AF_INET6 以指示您将绑定到 IPv6 地址)。请记住首先将 sin6_zero 字段清零。一种策略是将整个 sockaddr 结构清零,这会将 IPv6 地址设置为 IN6ADDR_ANY,这意味着您只需设置端口和地址系列。
  • 通过调用 listen() 进行监听

如果您仍然遇到问题,请发布您目前为止的代码。

如果我不得不猜测(因为你还没有发布任何代码),我认为它是否适用于 IPv4 并达到可以 accept() 连接,但 IPv6 连接 Accept() 调用返回 -1,我认为您可能没有传递 accept() 足够大的 struct sockaddr > 让它发挥作用。

例如,以下代码:

printf("sizeof(struct sockaddr_in) = %ld\n", sizeof(struct sockaddr_in));
printf("sizeof(struct sockaddr_in6) = %ld\n", sizeof(struct sockaddr_in6));

打印(在我的系统上):

sizeof(struct sockaddr_in) = 16
sizeof(struct sockaddr_in6) = 28

如果您只给 accept() 足够的空间来写出 IPv4 地址,则在接受 IPv6 连接时将会失败。确保分配 struct sockaddr_in6struct sockaddr_storage,并确保大小参数正确。

When accept() returns -1, errno will be set to indicate what specific error occurred. Please call perror("accept") for an easy way to see what the error was, and update your question with the results.

Also, please note that accept() must be called on a socket that has been:

  • Created using the socket() call. (you should pass PF_INET6 for the first argument of your socket to create an IPv6 protocol family socket)
  • Bound, using bind() using a struct sockaddr_in6 parameter as the 2nd parameter (with its sin6_family set to AF_INET6 for IPv6 to indicate you will be binding to an IPv6 address). Remember to zero out the sin6_zero field first. One strategy would be to zero the entire sockaddr structure, which would set the IPv6 address to IN6ADDR_ANY, which means you would just have to set the port and the address family.
  • Listening, by means of calling listen()

If you are still having trouble, post the code you have so far.

If I had to guess (since you haven't posted any code), I think if it works with IPv4 and gets to the point where it can accept() a connection, but IPv6 connection accept() calls return -1, I think it's likely that you aren't passing accept() a large enough struct sockaddr for it to work.

For example, the following code:

printf("sizeof(struct sockaddr_in) = %ld\n", sizeof(struct sockaddr_in));
printf("sizeof(struct sockaddr_in6) = %ld\n", sizeof(struct sockaddr_in6));

Prints (on my system):

sizeof(struct sockaddr_in) = 16
sizeof(struct sockaddr_in6) = 28

If you are only giving accept() enough room to write out an IPv4 address, it will fail when it accepts an IPv6 connection. Make sure you allocate either a struct sockaddr_in6 or a struct sockaddr_storage, and ensure the size argument is correct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文