Winsock:连接套接字问题

Winsock: connecting socket issue

我认为 connect() 函数对我来说工作不正常。我不知道问题是出在 "ip/port" 作业中还是在 hostinfo.sin_addr.s_addr = inet_addr(x)- 值。有人可以给我一个线索吗?顺便说一句,我是编程新手。

编译器让我回答 "HOST IP" 然后 "START PORT",但在我键入 "STOP PORT" 之前循环开始。

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


#include <string>
#include <WinSock2.h>
#include <Windows.h>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <stdio.h>

#define SCK_VERSION2 0x0202
#define WIN32_LEAN_AND_MEAN

using namespace std;


int main()
{
    dos_console();

    WSADATA wsadata;
    SOCKET sock;
    SOCKADDR_IN hostinfo;
    char ip[20];
    int start;
    int stop;
    int search;

    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
    {
        printf("ERROR: ");
    };

    printf("HOST IP: ");
    gets_s(ip);
    printf("START PORT: ");
    scanf_s("%s", &start);
    printf("STOP PORT: ");
    scanf_s("%s", &stop);

    hostinfo.sin_family = AF_INET;
    hostinfo.sin_addr.s_addr = inet_addr(ip);


    for (search = start; search <= stop; search++)
    {
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == INVALID_SOCKET)
        {
        printf("ERROR: ");
        }

        hostinfo.sin_port = htons(search);

        if (connect(sock, (SOCKADDR*)(&hostinfo), sizeof(hostinfo)) ==  SOCKET_ERROR)
        {
            printf("ERROR: ");
        }
        else
        {
            printf("PORT: ", search, " - OPEN");
            closesocket(sock);
            WSACleanup();
         }

         printf("PORTSCANNER: DONE");

    }

    system("PAUSE");
    return 0;
};

正如 jungy 在评论中所述,您的 startstop 变量是整数,但您使用 %sscanf_s() 读取它们,而您应该使用 %d 代替。您没有检查 gets_s()scanf_s() 的 return 值是否存在解析错误。

您还需要将 WSACleanup() 移出循环,否则如果 connect() 失败一次,则后续对 socket() 的调用将失败并出现 WSANOTINITIALISED 错误。

connect() 成功时,您也会泄漏每个套接字。

尝试更像这样的东西:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN

#include <string>
#include <WinSock2.h>
#include <Windows.h>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <stdio.h>

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

#define SCK_VERSION2 0x0202

using namespace std;

int main()
{
    dos_console();

    WSADATA wsadata = {0};
    SOCKET sock;
    SOCKADDR_IN hostinfo = {0};
    char ip[256] = {0};
    unsigned short start;
    unsigned short stop;
    unsigned short search;
    int ret;

    hostinfo.sin_family = AF_INET;

    ret = WSAStartup(MAKEWORD(2, 2), &wsadata);
    if (ret != 0)
    {
        printf("ERROR: WSAStartup() error %d\n", ret);
        goto done;
    }

    printf("HOST IP: ");
    if (!gets_s(ip))
    {
        printf("ERROR: HOST IP\n");
        goto cleanup;
    }

    hostinfo.sin_addr.s_addr = inet_addr(ip);
    if (hostinfo.sin_addr.s_addr == INADDR_NONE)
    {
        printf("ERROR: HOST IP\n");
        goto cleanup;
    }

    printf("START PORT: ");
    if (scanf_s("%hu", &start) != 1)
    {
        printf("ERROR: START PORT\n");
        goto cleanup;
    }

    printf("STOP PORT: ");
    if (scanf_s("%hu", &stop) != 1)
    {
        printf("ERROR: STOP PORT\n");
        goto cleanup;
    }

    if ((start == 0) || (stop == 0) || (stop < start))
    {
        printf("ERROR: PORT RANGE\n");
        goto cleanup;
    }

    for (search = start; search <= stop; search++)
    {
        sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sock == INVALID_SOCKET)
        {
            printf("ERROR: socket() error %d\n", WSAGetLastError());
            goto cleanup;
        }

        hostinfo.sin_port = htons(search);

        if (connect(sock, (SOCKADDR*) &hostinfo, sizeof(hostinfo)) ==  SOCKET_ERROR)
        {
            printf("PORT: %hu - NOT OPEN\n", search);
        }
        else
        {
            printf("PORT: %hu - OPEN\n", search);
        }

        closesocket(sock);    
    }

    printf("PORTSCANNER: DONE\n");

cleanup:
    WSACleanup();

done:
    system("PAUSE");
    return 0;
}

因为您无论如何都在使用 C++(从 using namespace std 语句可以看出),我会建议更像这样的东西:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>

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

#define SCK_VERSION2 MAKEWORD(2, 2)

using namespace std;

struct sWSA
{
    WSADATA wsadata;

    sWSA()
    {
        ZeroMemory(&wsadata, sizeof(wsadata));
        int ret = WSAStartup(SCK_VERSION2, &wsadata);
        if (ret != 0)
        {
            ostringstream oss;
            oss << "WSAStartup() error " << ret;
            throw runtime_error(oss.str());
        }
    }

    ~sWSA()
    {
        WSACleanup();
    }
};

struct sSocket
{
    SOCKET sock;

    sSocket()
    {
        sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sock == INVALID_SOCKET)
        {
            ostringstream oss;
            oss << "socket() error " << WSAGetLastError();
            throw runtime_error(oss.str());
        }
    }

    ~sSocket()
    {
        closesocket(sock);
    }

    bool connect(SOCKADDR_IN &host)
    {
        return (connect(sock, reinterpret_cast<SOCKADDR*>(&host), sizeof(host)) == 0);
    }
};

int main()
{
    dos_console();

    SOCKADDR_IN hostinfo = {0};
    string ip;
    unsigned short start;
    unsigned short stop;
    unsigned short search;

    hostinfo.sin_family = AF_INET;

    try
    {
        sWSA wsa;

        cout << "HOST IP: ";
        if (!getline(cin, ip))
            throw runtime_error("HOST IP");

        hostinfo.sin_addr.s_addr = inet_addr(ip.c_str());
        if (hostinfo.sin_addr.s_addr == INADDR_NONE)
            throw runtime_error("HOST IP");

        cout << "START PORT: ";
        if (!(cin >> start))
            throw runtime_error("START PORT");

        cout << "STOP PORT: ";
        if (!(cin >> stop))
            throw runtime_error("STOP PORT");

        if ((start == 0) || (stop == 0) || (stop < start))
            throw runtime_error("PORT RANGE");

        for (search = start; search <= stop; search++)
        {
            hostinfo.sin_port = htons(search);

            sSocket s;
            cout << "PORT: " << search << " - " << s.connect(hostinfo) ? "OPEN" : "NOT OPEN" << endl;
        }

        cout << "PORTSCANNER: DONE" << endl;
    }
    catch (const std::exception &e)
    {
        cout << "ERROR: " << e.what() << endl;
    }

    system("PAUSE");
    return 0;
}

现在我已经 decleraed、开始、停止、搜索为 unsigned short 并将它们读取为 (%hu),我还将 WSACleanup 移出循环并检查错误。它似乎工作但在我尝试使用 connect()

时给我一个错误
   if (connect(sock, (SOCKADDR*)(&hostinfo), sizeof(hostinfo))== SOCKET_ERROR)
    {
        printf("PORT: %hu - STÄNGD\n", search);
    }
    else
    {
        printf("PORT: %hu - ÖPPEN\n", search);  
    }
    closesocket(sock);

Remy Lebeau:我试图在我的编译器中复制并粘贴您的代码,我给了我一些错误,我根据我的编译器进行了更正,但它仍然在 connect() 中给我同样的错误。

我在防火墙 (5000-5010) 中打开了一些端口,但仍然出现此错误,我在一些较旧的线程中读到我必须将套接字配置为非阻塞套接字。这可能是问题所在吗?

现在这是我的代码:

 #define _WINSOCK_DEPRECATED_NO_WARNINGS

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

#include <stdio.h>
#include <iostream>
#include <string>
#include <WinSock2.h>
#include <Windows.h>
#include <cstring>
#include <fstream>
#include <cstdlib>
#include <iodos.h>
#include <sdkddkver.h>
#include <conio.h>


#define SCK_VERSION2 0x0202
#define WIN32_LEAN_AND_MEAN

 using namespace std;


 int main()
{
   dos_console();

    WSADATA wsadata;
    SOCKET sock;
    SOCKADDR_IN hostinfo;
    char ip[20];
    unsigned short start;
    unsigned short stop;
    unsigned short search;
    int err;

    hostinfo.sin_family = AF_INET;
    err = WSAStartup(MAKEWORD(2, 2), &wsadata);

    if (err != 0)
    {
         printf("ERROR: Wsadata error");
    };
    printf("HOST IP: ");
    if (!gets_s(ip))
    {
        printf("ERROR: HOST IP error");
        goto cleanup;
    }

    hostinfo.sin_addr.s_addr = inet_addr(ip);

    if (hostinfo.sin_addr.s_addr == INADDR_NONE)
    {
        printf("ERROR: HOST IP 2 error");
        goto cleanup;
    }
    printf("START PORT: ");
    if (scanf_s("%hu", &start) != 1)
    {
        printf("ERROR: START PORT");
        goto cleanup;
    }
    printf("STOP PORT: ");
    if (scanf_s("%hu", &stop) != 1)
    {
        printf("ERROR: STOP PORT");
        goto cleanup;
    }


    for (search = start; search <= stop; search++)
    {
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET)
    {
        printf("ERROR: socket error"), WSAGetLastError();
    }

    hostinfo.sin_port = htons(search);

    if (connect(sock, (SOCKADDR*)(&hostinfo), sizeof(hostinfo))== SOCKET_ERROR)
    {
            printf("PORT: %hu - STÄNGD\n", search);
        }
        else
        {
            printf("PORT: %hu - ÖPPEN\n", search);  
        }
        closesocket(sock);

    }
    printf("PORTSCANNER DONE");
    cleanup:
    WSACleanup();
    done:
    system("PAUSE");
    return 0;
};