4

getaddrinfo()ホスト名を IP アドレスに変換しないconnect()ため、サーバーには変換されません。実装に何か問題がありますか?警告メッセージなしでコンパイルされますか?

この関数呼び出しはconnect正しいですか?

connect(client, result->ai_addr, result->ai_addrlen)

以下にリストされている完全な実装:

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdio.h>
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

using namespace std;

int main (
          int argc,
          char* argv[])
{
if (argc != 3)
{
    cerr << "Usage: " << argv[0] << " [hostname] [port number]\n";
    exit(EXIT_FAILURE);
}

WSADATA wsaData;
WORD wVersionRequested;
int wError;

wVersionRequested = MAKEWORD(2, 2);

wError = WSAStartup(wVersionRequested, &wsaData);

if (wError != 0)
{
    cerr << "WSAStartup failed with error: " << wError << endl;
    exit (EXIT_FAILURE);
}

/*
* Confirm that the WinSock DLL supports 2.2.
* Note that if the DLL supports versions greater
* than 2.2 in addition to 2.2, it will still return 
* 2.2 in wVersion since that is the version we 
* requested. 
*/

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
    cerr << "Could not find a usable version of Winsock.dll." << endl;
    WSACleanup();
    exit(EXIT_FAILURE);
} else {
    cout << "The Winsock 2.2 dll was found." << endl;
}

SOCKET client;

if ((client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR)
{
    cerr << "Error: socket() return value == SOCKET_ERROR" << endl;
    WSACleanup();
    exit (EXIT_FAILURE);
}

cout << "Created a socket." << endl;

struct addrinfo *result = NULL;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

if ((wError = getaddrinfo(
                    argv[1],
                    argv[2],
                    &hints,
                    &result)) !=0 )
{
    freeaddrinfo(result);
    WSACleanup();
    if (wError == 11001)
    {
        cerr << "Error: occurred: getaddrinfo() failed "
             << wError << " - Host not found." << endl;
        exit(EXIT_FAILURE);
    }

    cerr << "Error: occurred: getaddrinfo() failed "
            << wError << endl;
    exit(EXIT_FAILURE);
}
/*
* Attempt to connect to the Server
*
*/

switch (wError = connect(client, result->ai_addr, result->ai_addrlen)) {
    case 0:
        cerr << "Resolved hostname." << endl;
        break;
    case SOCKET_ERROR:
        wError = WSAGetLastError();
        cerr << "Error: connet() failed "
                "Details: " << wError << endl;
        closesocket(client);
        freeaddrinfo(result);
        WSACleanup();
        exit(EXIT_FAILURE);
        break;
    default:
        cerr << "Fatal connect() error: unexpected "
                "return value." << endl;
        closesocket(client);
        freeaddrinfo(result);
        WSACleanup();
        exit(EXIT_FAILURE);
        break;
}

cout << "Connected to server." << endl;

closesocket(client);
freeaddrinfo(result);
WSACleanup();
exit(EXIT_SUCCESS);
}
4

2 に答える 2

4

getaddrinfoIPv6 アドレスを提供している可能性があります。または、マシンに複数の IP アドレスがあり、間違った IP アドレスに接続しようとしている可能性があります。

また、サーバーが 127.0.0.1 でリッスンしている場合、実際の IP アドレスに接続しようとすると、接続は失敗します。同様に、サーバーが実際の IP アドレスをリッスンしている場合、127.0.0.1 を使用して接続しようとすると、接続は失敗します。サーバーが 0.0.0.0 でリッスンする場合、両方のアドレスが機能するはずです。

0.0.0.0 でリッスンするには、次のようなコードになります。

sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port=htons( port_num );
bind( s, (sockaddr *)&sin, sizeof( sin ) );
于 2009-01-29T02:57:20.543 に答える
1

の代わりにをに設定してみてくださいhint.ai_family。が指定されている場合、IPv4のようなアドレスを除いてgetaddrinfo関数が機能すると思います。AF_UNSPECAF_INETAF_INET

于 2009-01-29T02:15:04.887 に答える