即使将SO

编程入门 行业动态 更新时间:2024-10-28 20:28:26
本文介绍了即使将SO_REUSEADDR与IPv6一起使用,套接字绑定也会失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我的应用程序需要在具有相同IPv6地址的同一端口上绑定套接字.我正在使用下面的代码来实现相同的目的.但是,第二个绑定会引发错误地址已在使用中". 顺便说一句,只有当我包含第一个套接字的监听调用时,我才会收到此错误.没有监听调用,第二个套接字绑定就可以了.

My application needs to bind a socket on the same port with the same IPv6 address. I am using the code below to achieve the same. However second bind throws an error 'Address already in use'. BTW, i get this error only if I include the listen call for the first socket. Without the listen call, the second socket binds just fine.

我做错了什么?请帮助我理解.

What I am doing wrong? Please help me understand.

谢谢

int fd1 = ::socket(AF_INET6, SOCK_STREAM, 0); if (fd1 < 0) { perror("fd1 socket()"); return -1; } // Set SO_REUSEADDR for both sockets int reuse = 1; if (fcntl(fd1, F_SETFL, O_RDWR|O_NONBLOCK) <0) { perror("fd1 fcntl64 failed"); return -1; } if (::setsockopt(fd1, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { perror("fd1 SO_REUSEADDR failed"); return -1; } if (::setsockopt(fd1, SOL_IPV6, IPV6_V6ONLY, &reuse, sizeof(reuse)) < 0) { perror("fd1 SO_REUSEADDR failed"); return -1; } sockaddr_storage storage; socklen_t addrlen = sizeof(storage); memset(&storage, 0, addrlen); sockaddr_in6& addr = reinterpret_cast<sockaddr_in6&>(storage); addr.sin6_family = AF_INET6; addr.sin6_port = 143; addr.sin6_addr = in6addr_any; sockaddr* pAddr = reinterpret_cast<sockaddr*>(&storage); int val = 2; socklen_t len = sizeof(val); if (::getsockopt(fd1, SOL_SOCKET, SO_REUSEADDR, &val, &len) < 0) { perror("fd1 getsock failed"); return -1; } printf("Getsockopt returned %d at %d\n",val, __LINE__); if (::bind(fd1, pAddr, sizeof(sockaddr_in6)) < 0) { perror("bind fd1 failed"); return -1; } if (::getsockopt(fd1, SOL_SOCKET, SO_REUSEADDR, &val, &len) < 0) { perror("fd1 getsock failed"); return -1; } printf("Getsockopt returned %d at %d\n",val, __LINE__); if (listen(fd1, 128) < 0) { perror("fd1, listen"); return -1; } if (::getsockopt(fd1, SOL_SOCKET, SO_REUSEADDR, &val, &len) < 0) { perror("fd1 getsock failed"); return -1; } printf("Getsockopt returned %d at %d\n",val, __LINE__); // Get the local address for fd1 addrlen = sizeof(storage); if (::getsockname(fd1, pAddr, &addrlen)) { perror("getsockname for fd1 failed"); return -1; } char straddr[INET6_ADDRSTRLEN]; if (!inet_ntop(AF_INET6, &addr.sin6_addr, straddr, sizeof(straddr))) { perror("inet_ntop for fd1 failed"); return -1; } printf("fd1=%d addr=%s:%d\n", fd1, straddr, addr.sin6_port); addrlen = sizeof(storage); addr.sin6_family = AF_INET6; addr.sin6_port = 143; int fd2 = ::socket(AF_INET6, SOCK_STREAM, 0); if (fd2 < 0) { perror("fd2 socket()"); return -1; } if (::setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { perror("fd2 SO_REUSEADDR failed"); return -1; } if (::setsockopt(fd2, SOL_IPV6, IPV6_V6ONLY, &reuse, sizeof(reuse)) < 0) { perror("fd1 SO_REUSEADDR failed"); return -1; } if (::bind(fd2, pAddr, sizeof(sockaddr_in6)) < 0) { perror("bind fd2 failed"); return -1; } // Get the local address for fd2 if (::getsockname(fd2, pAddr, &addrlen)) { perror("getsockname for fd2 failed"); return -1; } if (!inet_ntop(AF_INET6, &addr.sin6_addr, straddr, sizeof(straddr))) { perror("inet_ntop for fd2 failed"); return -1; } printf("fd2=%d addr=%s:%d\n", fd2, straddr, addr.sin6_port); return 0;

推荐答案

在socket(7)手册页中:

SO_REUSEADDR-指示用于验证bind(2)调用中提供的地址的规则应允许重用本地地址.对于AF_INET套接字,这意味着套接字可以绑定,除外,除非有活动的监听套接字绑定到该地址.当侦听套接字使用特定端口绑定到INADDR_ANY时,则不可能将其绑定到任何本地地址.参数是一个整数布尔值标志.

SO_REUSEADDR - Indicates that the rules used in validating addresses supplied in a bind(2) call should allow reuse of local addresses. For AF_INET sockets this means that a socket may bind, except when there is an active listening socket bound to the address. When the listening socket is bound to INADDR_ANY with a specific port then it is not possible to bind to this port for any local address. Argument is an integer boolean flag.

(重点是我的)

您的第一个套接字绑定到与INADDR_ANY等效的IPv6上的端口143,然后进入侦听状态.因此,只要第一个插座保持打开状态,端口143上就不会绑定其他插座.

Your first socket is bound to port 143 on the IPv6 equivalent of INADDR_ANY, then it's put in listening state. Thus no other socket could be bound on port 143 as long as the first socket remains open.

更多推荐

即使将SO

本文发布于:2023-11-06 15:55:14,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1564137.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!