2016-12-29 79 views
1

使用以下代码我可以绑定到ipv4地址,但不绑定到也绑定到该地址的作用域全局ipv6地址机。我编译这样的代码:无法使用Net :: DatagramSocket获取poco 1.6.1或1.7.6绑定到ipv6

g++ -lPocoFoundation -lPocoXML -lPocoUtil -lPocoNet -lcrypto -lssl -I/usr/include/Poco -o pocoudpipv6 pocoudpipv6.cpp

当我执行./pocoudpipv6 10.X.X.X,它拥有打开插座和周期的“请稍候”,直到我打CTRL-C,这是预期。台报告插座:

# ss -nelup |grep 20000 UNCONN 0 0 10.X.X.X:20000 *:* users:(("pocoudpipv6",pid=2444,fd=3)) uid:1000 ino:14526705 sk:2a <->

但是,当我与./pocoudpipv6 2001:X:X:X::X:X执行,出现这种情况:

我们从:: 1到2001重置ip地址:X:X:X :: X: X 地址族是ipv6 启动失败。错误是网络例外:不支持地址系列

在Slackware64 14.2以及在Debian 8 jessie amd64上的1.6.1上发生此问题。据我读过,在Poco中启用ipv6应该是默认的。为了让这个测试用例能够使用ipv6,还有什么我需要做的吗?

而且我至少有一个守护程序绑定到IPv6套接字这台机器上:

udp UNCONN 0 0 2001:X:X:X::X:X:123 :::* users:(("ntpd",pid=2133,fd=22)) ino:5247 sk:19 v6only:1 <->

提前感谢!

代码如下:

#include <iostream> 
#include <Net/DatagramSocket.h> 
#include <Net/SocketAddress.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <signal.h> 

struct sigaction sigact = { 0 }; 

struct io_handling { 
     uint8_t exit_value; 
}; 

struct io_handling io_handler = { 0 }; 

static void sigint_signal_handler(int sig) 
{ 
    if(sig == SIGINT) { 
     std::cout << std::endl << "Commencing shutdown in 5... 4... 3... 2... 1..." << std::endl; 
     io_handler.exit_value = 1; 
    } 
} 

static void cleanup(void) 
{ 
    sigemptyset(&sigact.sa_mask); 
} 

int main(int argc, char **argv) 
{ 
    Poco::Net::DatagramSocket *pSocket = new Poco::Net::DatagramSocket(); 
    Poco::UInt16 port = 20000; 
    Poco::Net::IPAddress *ipAddress = new Poco::Net::IPAddress("::1"); 

    if(argc == 2) { 
     delete ipAddress; 
     ipAddress = new Poco::Net::IPAddress(argv[1]); 
     std::cout << std::endl << "We're resetting the ipaddress from ::1 to " << argv[1]; 
    } 

    std::cout << std::endl << "Address family is "; 

    if(ipAddress->family() == static_cast<Poco::Net::IPAddress::Family>(Poco::Net::Impl::IPAddressImpl::IPv6)) { 
     std::cout << "ipv6 "; 
    } else if(ipAddress->family() == static_cast<Poco::Net::IPAddress::Family>(Poco::Net::Impl::IPAddressImpl::IPv4)) { 
     std::cout << "ipv4 "; 
    } else { 
     std::cout << "something else, something very wrong."; 
    } 

    try { 
     sigact.sa_handler = sigint_signal_handler; 
     sigemptyset(&sigact.sa_mask); 
     sigact.sa_flags = 0; 
     sigaction(SIGINT, &sigact, (struct sigaction *)NULL); 

     pSocket->bind(Poco::Net::SocketAddress(*ipAddress, port)); 
     while(!io_handler.exit_value) { 
      sleep(1); 
      std::cout << std::endl << "Waiting..."; 
     } 
    } catch(Poco::Exception& ex) { 
     std::cout << std::endl << "Failure launching. Error was " << ex.displayText() << std::endl; 
    } 

    delete pSocket; 
    delete ipAddress; 

    return 0; 
} 
+0

自解决。我正在使用的lib只调用Poco :: Net :: DatagramSocket的默认ctor,然后给出一个仅用于ipv4的套接字。调用:: bind()不会根据输入的IP地址重置。 –

回答

0

自行解决。我正在使用的lib只调用Poco :: Net :: DatagramSocket的默认ctor,然后给出一个仅用于ipv4的套接字。调用:: bind()不会根据输入的IP地址重置。

解决方法是在上面的例子中处理ipAddress之前不是新的pSocket,然后将该端口作为Poco :: Net :: SocketAddress传递给ctor,它将创建合适的套接字类型并自动绑定它。

相关问题