微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么WSAConnect套接字在有效主机上超时

如何解决为什么WSAConnect套接字在有效主机上超时

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

以下是代码

#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);
    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);
    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通它)
  • 我尝试禁用防火墙和防病毒

我的猜测

由于我没有超时以外的错误代码,所以我想知道某些标准是否发生了变化,并且会干扰它应该起作用的方式。

感谢您的时间

解决方法

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);
        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",rport);

        iResult = WSAConnect(sock,addr->ai_addr,addr->ai_addrlen,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();
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。