Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;连接到IPv4地址时,winsock连接被拒绝_C++_Winsock_Connect_Ipv6_Ipv4 - Fatal编程技术网

C++ C++;连接到IPv4地址时,winsock连接被拒绝

C++ C++;连接到IPv4地址时,winsock连接被拒绝,c++,winsock,connect,ipv6,ipv4,C++,Winsock,Connect,Ipv6,Ipv4,我正在使用winsock2编程一个服务器/客户端系统,当我将客户端连接到服务器名称或服务器IPv6地址时,它工作得非常好。但是,当我使用服务器IPv4地址时,在客户端中调用connect()时会出现错误“Connection seeded” 此错误发生在我的客户端或使用telnet时。但是,我可以使用IPv4或IPv6这三个名称中的任何一个成功ping服务器 我尝试过在同一台机器上运行服务器和客户端,在不同的机器上运行,并且在所有机器上禁用防火墙 以下是我的服务器初始化和侦听代码的摘录: SOC

我正在使用winsock2编程一个服务器/客户端系统,当我将客户端连接到服务器名称服务器IPv6地址时,它工作得非常好。但是,当我使用服务器IPv4地址时,在客户端中调用connect()时会出现错误“Connection seeded”

此错误发生在我的客户端或使用telnet时。但是,我可以使用IPv4或IPv6这三个名称中的任何一个成功ping服务器

我尝试过在同一台机器上运行服务器和客户端,在不同的机器上运行,并且在所有机器上禁用防火墙

以下是我的服务器初始化和侦听代码的摘录:

SOCKET sockfd = INVALID_SOCKET, in_socketID;
struct addrinfo hints;
struct addrinfo *servinfo = NULL;
struct addrinfo *p;
struct addrinfo *ip;
sockaddr_storage incoming_addr;
int addr_size;
int tmp_err;
const char *sPort = "20152";

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // either IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;

tmp_err = getaddrinfo(NULL, sPort, &hints, &servinfo);
if (tmp_err != 0)
    throw exception("ERROR: getaddrinfo failed");

// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL && sockfd == INVALID_SOCKET; p = p->ai_next)
{
    ip = p;
    sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
    if (sockfd == INVALID_SOCKET)
    {
        cerr << "ERROR on socket(): " << WSAGetLastError() << endl;
    } // end if
    else if (bind(sockfd, p->ai_addr, p->ai_addrlen) == SOCKET_ERROR)
    {
        cerr << "ERROR on bind(): " << WSAGetLastError() << endl;
        closesocket(sockfd);
        sockfd = INVALID_SOCKET;
    } // end if
} // end for

if (sockfd == INVALID_SOCKET)
{
    // looped off the end of the list with no successful bind
    throw exception("ERROR: Failed to bind socket");
}

// clean up
if (servinfo)
    freeaddrinfo(servinfo);

if (listen(sockfd, SOMAXCONN ) == SOCKET_ERROR)
    throw exception("Listen failed");

while (true)
{
    memset(&incoming_addr, 0, sizeof(incoming_addr));
    addr_size = sizeof(incoming_addr);
    in_socketID = accept(socketID, (sockaddr *)&incoming_addr, &addr_size);

    // do stuff with incoming connection
}

我知道它显然会起作用,但当我这样做时,IPv6当然不起作用

看起来用户Sorayuki是对的,我的循环连接到了IPv6

似乎没有简单的方法来统一IPv6和IPv4。您的套接字必须侦听其中一个,这使得该过程非常烦人

根据文档,同时侦听IPv4和IPv6的旧式方式是为每种协议创建一个套接字,并同时侦听这两种协议。这适用于Windows Server 2003和Windows XP SP1

首选的现代风格(WindowsVista,7和8)是将您的套接字转换为双套接字,它将同时侦听IPv4和IPv6。但是,您的客户机还必须能够设置双套接字,因此,如果您的应用程序正在为旧客户机服务,那么您将无法使用旧方法


谢谢

您是否尝试在同一台计算机上运行服务器和客户端

这听起来像是防火墙问题。
如果您成功地将telnet/应用程序连接到同一台机器上,您就会知道这就是问题所在。

是因为您将服务器套接字绑定到IPv6地址吗? 在“for”循环中,出现在IPv4地址之前的IPv6地址似乎会导致服务器的套接字侦听IPv6地址。 因此,您的服务器未侦听任何IPv4地址,因为所有指向服务器IPv4地址的连接都被拒绝


使用工具或某些命令(如netstat)尝试查看所有侦听端口上的IP地址这是因为绑定到IPv6地址不会神奇地绑定到IPv4地址

在Linux上,默认情况下绑定到
[::]
将导致IPv6和IPv4工作(除非
/proc/sys/net/IPv6/bindv6only
设置为
1

但是,在Mac OS X和Windows上,绑定到
[::]
仅适用于IPv6。您还必须绑定到IPv4地址(或
0.0.0.0
)才能使其工作


您在注释“循环所有结果并绑定到第一个结果”中描述的逻辑正是这里的问题。您应该使用
IPV6_V6ONLY
标志(请参见
setsockopt()
)和
0.0.0

绑定到
[::]
,是的,我意识到了这一点。谢谢你的回答:)。我修复了我的代码,现在正在工作。没问题。请用勾号将此答案标记为正确答案,谢谢。
int sockfd = INVALID_SOCKET;
struct addrinfo hints;
struct addrinfo *servinfo = NULL;
struct addrinfo *p;
struct addrinfo *ip;
int tmp_err;
const char *sHost = "192.168.1.136";
const char *sPort = "20152";

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // either IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // use TCP

tmp_err = getaddrinfo(sHost,        // web address or ip to connect to
                      sPort,        // port or protocol
                      &hints,       // initialized hints structure
                      &servinfo);   // return structure
if (tmp_err != 0)
    throw exception("ERROR: getaddrinfo failed");

// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL && sockfd == INVALID_SOCKET; p = p->ai_next)
{
    ip = p;
    sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
    if (sockfd == INVALID_SOCKET)
    {
        cerr << "ERROR on socket(): " << WSAGetLastError() << endl;
        //continue;
    } // end if
    else if (connect(sockfd, p->ai_addr, p->ai_addrlen) < 0)
    {
        cerr << "ERROR on connect(): " << WSAGetLastError() << endl;
        closesocket(sockfd);
        sockfd = INVALID_SOCKET;
        //continue;
    } // end if
} // end for

if (sockfd == INVALID_SOCKET)
    throw exception("ERROR: Failed to connect");


// clean up
if (servinfo)
    freeaddrinfo(servinfo);

// do stuff with new socket
hints.ai_family = AF_UNSPEC;
hints.ai_family = AF_INET;