【问题标题】:Why does WSAConnect socket Timeout on valid host为什么有效主机上的 WSAConnect 套接字超时
【发布时间】:2020-12-22 16:12:49
【问题描述】:

我试图回到一个旧的 C 项目,但从一开始它就不再工作了。 基本上它所做的是它只是为远程主机(我可以 ping)创建一个套接字(使用 WSAConnect),但每次尝试连接到远程主机时我都会超时。

代码如下:

#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 1024

void BindSock(char* rhost, int rport);

int main(int argc, char** argv) {
    //FreeConsole(); // This is the way to make the cmd vanish
    char rhost[] = "g0blin.ovh"; // ip to connect to
    int rport = 1111;
    BindSock(rhost, rport);
    return 0;
}
void BindSock(char* rhost, int rport) {
    /*while (1) {*/
    SECURITY_ATTRIBUTES saAttr;
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    // Initialize Winsock
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        printf("WSAStartup function failed with error: %d\n", iResult);
        return;
    }
    printf("[*] Winsock init ... \n");
    //init socket props
    SOCKET sock;
    sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
    if (sock == INVALID_SOCKET) {
        printf("socket function failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return;
    }
    printf("[*] Sock init ... \n");
    //Filling struc props
    struct sockaddr_in clientService;
    clientService.sin_family = AF_INET;
    InetPton(AF_INET, rhost, &(clientService.sin_addr));
    clientService.sin_port = htons(rport);

    printf("[*] attempting to connect \n");
    iResult = WSAConnect(sock, (SOCKADDR*)&clientService, sizeof(clientService), NULL, NULL, NULL, NULL);
    if (iResult == SOCKET_ERROR) {
        printf("[!] connect function failed with error: %ld\n", WSAGetLastError());
        iResult = closesocket(sock);
        if (iResult == SOCKET_ERROR)
            printf("[!] closesocket function failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return;
    }
    printf("[X] Sock Connected\n");

到目前为止我尝试了什么:

  • 我尝试 ping 主机,我可以
  • 我更改了远程主机,但它不起作用(我也可以 ping 它)
  • 我尝试禁用防火墙和防病毒软件

我的猜测

由于除了 Timeout 之外我没有错误代码,我想知道是否某些标准发生了变化,并且它会干扰它应该工作的方式。

感谢您的宝贵时间

【问题讨论】:

  • 尝试使用 LocalHost (127.0. 0.1) 作为 rhost 进行快速测试。
  • InetPton 是做名称解析还是只能处理文本形式的数字 IP 地址? (例如“127.0.0.1”)检查clientService.sin_addr中的返回值和结果
  • @ryyker 我试过 localhost 也没用
  • LocalHost ( 127.0. 0.1 ) 并使用 rport = 80 我能够在没有其他更改的情况下连接。这表明需要查看您的 IP/Port 值。 Web 服务器端口通常是 80,而 SMTP 服务器使用 25。你确定1111 是正确的IP 地址吗?
  • 您是否尝试过通过其他程序连接到该端口?例如curl、telnet 或网络浏览器?可能被某处的防火墙阻止

标签: c++ c windows sockets winapi


【解决方案1】:

g0blin.ovh 不是 IPv4 地址的字符串表示,它是主机名,因此 InetPton() 将无法解析它,但您没有检查该条件,因此您传递了无效的 sockaddr_inWSAConnect()

您需要改用getaddrinfo(),它将解析IP 地址字符串,并根据需要执行主机名查找。除了 IPv4 之外,它还允许您支持 IPv6。例如:

#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 1024

void BindSock(const char* rhost, unsigned short rport);

int main(int argc, char** argv) {
    //FreeConsole(); // This is the way to make the cmd vanish
    char rhost[] = "g0blin.ovh"; // ip to connect to
    unsigned short rport = 1111;
    BindSock(rhost, rport);
    return 0;
}

void BindSock(const char* rhost, unsigned short rport) {
    // Initialize Winsock
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        printf("WSAStartup function failed with error: %d\n", iResult);
        return;
    }
    printf("[*] Winsock init ... \n");

    //lookup host
    struct addrinfo hints = {0}, *result;
    hints.ai_family = AF_INET;// use AF_UNSPEC instead to handle IPv4 + IPv6 together...
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    char szport[6] = {};
    sprintf(szport, "%hu", rport);

    iResult = getaddrinfo(rhost, szport, &hints, &result);
    if (iResult != NO_ERROR) {
        printf("getaddrinfo function failed with error: %d\n", iResult);
        WSACleanup();
        return;
    }
    printf("[*] host found ... \n");

    //init socket props
    SOCKET sock = INVALID_SOCKET;
    for(struct addrinfo *addr = result; addr != NULL; addr = addr->ai_next)
    {
        sock = WSASocketW(addr->ai_family, addr->ai_socktype, addr->ai_protocol, 0, 0, 0);
        if (sock == INVALID_SOCKET) {
            printf("socket function failed with error: %ld\n", WSAGetLastError());
            continue;
        }
        printf("[*] Sock init ... \n");

        char ip[46] = {0};
        void *psin_addr;

        switch (addr->ai_family)
        {
            case AF_INET:
                psin_addr = &(((struct sockaddr_in*)addr->ai_addr)->sin_addr);
                break;

            case AF_INET6:
                psin_addr = &(((struct sockaddr_in6*)addr->ai_addr)->sin6_addr);
                break;
        }

        inet_ntop(addr->ai_family, psin_addr, ip, sizeof(ip));
        printf("[*] attempting to connect to %s:%hu\n", ip, rport);

        iResult = WSAConnect(sock, addr->ai_addr, addr->ai_addrlen, NULL, NULL, NULL, NULL);
        if (iResult != SOCKET_ERROR) {
            printf("[X] Sock Connected\n");
            break;
        }

        printf("[!] connect function failed with error: %ld\n", WSAGetLastError());
        closesocket(sock);
        sock = INVALID_SOCKET;
    }

    freeaddrinfo(result);

    if (sock == INVALID_SOCKET)
    {
        WSACleanup();
        return;
    }

    // use sock as needed ...

    closesocket(sock);
    WSACleanup();
}

【讨论】:

  • 感谢您的回答,但不幸的是,我更改了一段时间,转到基本 IP,但它不起作用,如果代码对您有效,我会假设我的电脑有问题
猜你喜欢
  • 2011-10-19
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
相关资源
最近更新 更多