Winsock 代码不工作

Winsock code not working

我已经完成了我的 c++ 教程并开始使用 winsock,但对这个主题还是有点陌生​​。我制作了一个客户端代码,试图使用端口 80 (http) 连接到网站,但每当我 运行 它时,我都会收到错误代码 10049,并且它没有连接到服务器。这是代码..

Defenitions.h:

#include <iostream>
#include <winsock2.h>

using namespace std;

//Prototypes:
WORD version = MAKEWORD(2, 2);
WSADATA info;
SOCKET hSocket;
USHORT port;
sockaddr_in hSockAddr;
char website[50];
void initWSA();
void createSocket();
hostent* websiteInfo;
void getPort();
void connectSocket();
void cleanUp();

//Functions:
void initWSA(){
    if(WSAStartup(version, &info) == 0){
        cout << "WinSock initialization successful!" << endl;
    }else{
        cout << "WinSock initialization failed!" << endl;
    }
}
void createSocket(){
    hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(hSocket != INVALID_SOCKET){
        cout << "Socket Creation Successful!" << endl;
    }else{
        cout << "Socket Creation Failed!" << endl;
    }
}
void getPort(){
    cout << "Enter the port number to connect to:" << endl;
}
void connectSocket(){
    if(connect(hSocket, (SOCKADDR*)&hSockAddr, sizeof(hSockAddr)) == 0){
        cout << "Connection to server successful!" << endl;
    }else{
        cout << "Connection to server failed! error code: " << WSAGetLastError() << endl;
    }
}

void cleanUp(){
    if(closesocket(hSocket) == 0){
        cout << "Socket Closure Successful!" << endl;
    }else{
        cout << "Socket Closure Failed!" << endl;
    }
    if(WSACleanup() == 0){
        cout << "WinSock cleanup successful!\a" << endl;
    }else{
        cout << "WinSock cleanup failed!\a" << endl;
    }
}

main.cpp:

#include "Definitions.h"

int main(int argc, char *argv[]){
    initWSA();
    createSocket();
    cout << "IP Address of: " << "www.google.com" << " is: "<< gethostbyname("www.google.com") << endl;
    getPort();
    cin >> port;
    hSockAddr.sin_family = AF_INET;
    hSockAddr.sin_port = htons(port);
    hSockAddr.sin_addr.S_un.S_addr = inet_addr("www.google.com");
    connectSocket();
    cleanUp();
    return 0;
}

这总是我得到的:

有什么建议吗?

参见Windows Sockets Error Codes,在本例中:

WSAEADDRNOTAVAIL
10049

Cannot assign requested address.

The requested address is not valid in its context. This normally results from an attempt to bind to an address that is not valid for the local computer. This can also result from connect, sendto, WSAConnect, WSAJoinLeaf, or WSASendTo when the remote address or port is not valid for a remote computer (for example, address or port 0).

你看到你的IP地址输出了吗?我想这不是你想要的。

我认为您应该查看此示例以获取 IP 地址:

Winsock 程序员常见问题解答
示例:Get the Local IP Address(es)

问题在于如何将主机地址转换为 ip,

inet_addr 用于 ip 地址:

The inet_addr function converts a string containing an IPv4 dotted-decimal address into a proper address for the IN_ADDR structure.

而不是:

hSockAddr.sin_addr.S_un.S_addr = inet_addr("www.google.com");

使用:

struct hostent *he = gethostbyname("www.google.com");
memcpy(&hSockAddr.sin_addr, he->h_addr_list[0], he->h_length);

// Or:
//hSockAddr.sin_addr.s_addr = ((in_addr *)(he->h_addr))->s_addr;

看这里:converting host to ip by sockaddr_in gethostname etc

[编辑]

正如 Remy Lebeau 在评论中所写,gethostbyname 已被弃用,应该使用 getaddrinfo,下面是使用 getaddrinfo 的示例代码:

  // Resolve host name
  struct addrinfo hints, *servinfo, *p;
  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  int rv;
  std::string str_port = std::to_string(port);
  if ((rv = getaddrinfo("www.google.com", str_port.c_str(), &hints, &servinfo)) != 0) {
    std::cerr << "getaddrinfo: " << rv << ": " << gai_strerrorA(rv) << std::endl;
    return 1;
  }

  // Loop over all returnd addresses, first one that works is the one we want to use
  for (p = servinfo; p != NULL; p = p->ai_next) {
    createSocket();
    if (connect(hSocket, p->ai_addr, p->ai_addrlen) == 0) {
      cout << "Connection to server successful!" << endl;
      break;
    }
    else {
      cout << "Connection to server failed! error code: " << WSAGetLastError() << endl;
      closesocket(hSocket);
    }
  }
  freeaddrinfo(servinfo);