Address already in use
当同时监听某个端口的IPv4和IPv6时,运行bind函数将执行失败,提示“bind : Address already in use”。
原因:ipv6的socket默认情况下也会接收ipv4的报文,不同的socket不能监听同IP 下的同端口
方法:设置ipv6的socket只接收ipv6地址的报文
int on = 1;
if(0 > setsockopt(fd_v6, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)))
{
perror("setsockopt");
return -1;
}
IPv6相关
- fe80 本地链路IPv6 地址,只用于本地使用,不能用于往外通信
- 访问ipv6的web服务器http://[fe80::aa:bb:cc:dd],带有中括号的访问
- ping IPv6,如果是fe80开头的,则ping6 fe80::aa:bb:cc:dd%xx,添加%后面加网卡名
- ping IPv6,如果非fe80开头的,则ping6 fe80::aa:bb:cc:dd即可
- 使用boost添加网络链接时,IPv6也应该是fe80::aa:bb:cc:dd%xx才可
如何使用boost的asio实现同时监听IPv4和IPv6
boost::asio::io_service io_serv;
boost::asio::ip::tcp::acceotpr acceotor_v4(io_serv);
boost::asio::ip::tcp::acceotpr acceotor_v6(io_serv);
acceotor_v4.open(ip::tcp::v4());
acceotor_v6.open(ip::tcp::v6());
设置属性
//设置IPv6仅接收IPv6地址
setsockopt(fd_v6, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on);
无地址绑定
//绑定IPv4
acceotor_v4.bind(ip::tcp::endpoint(ip::tcp::v4(), port));
//绑定IPv6
acceotor_v6.bind(ip::tcp::endpoint(ip::tcp::v6(), port));
有地址绑定
boost::asio::ip::address addr = boost::asio::ip::address::from_string(ip);
acceotor_v4.bind(ip::tcp::endpoint(addr, port));