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);
}
getaddrinfo
可能为您提供了 IPv6 地址,或者机器可能有多个 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 ) );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)