winsock всегда возвращает -1 в сокете - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь подключиться к своему серверу через порт 69, используя winsock2.h. Кажется, что все компилируется правильно, но в отладчике maincommsock всегда равен -1. Я не могу понять, почему это не работает, и мне нужна помощь. Не очень опытный в программировании сокетов, и не уверен, что делать сейчас! Любая помощь будет принята с благодарностью.

Я не уверен на 100%, что еще можно попробовать. В основном это функция, которая устанавливает соединение на сокете и устанавливает для соединения значение true, чтобы оно могло зацикливаться до тех пор, пока не будет установлено соединение.

    int maincommsock;
    bool connection = false;

static void establishconn() {
    maincommsock = socket(AF_INET, SOCK_STREAM, 0);
    if (maincommsock == -1) {
        connection = false;
    }

    //OutputDebugString((LPCSTR)commservers[1]);

    /*
    struct hostent *host;
    if ((host = gethostbyname(SERV_ADDR)) == NULL) {
        connection = FALSE;
    }
    */
    SOCKADDR_IN sockaddr;
    sockaddr.sin_port = 69;
    sockaddr.sin_family = AF_INET;
    sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    //sockaddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
    if (connect(maincommsock, (SOCKADDR *)(&sockaddr), sizeof(sockaddr)) != 1) {
        connection = true;
    }
}

EDIT

Я использовал WSAStartup, и в настоящее время я получаю сообщение об ошибке: Невозможно установить соединение, поскольку целевая машина активно отказала ему. "

РЕДАКТИРОВАТЬ 2

использовал htons на порт. В нем говорится, что операция успешно завершена, но на сервере не отображаются соединения

РЕДАКТИРОВАТЬ 3

Я собираюсь протестировать его на linux, чтобы убедиться, что это действительно ошибка на стороне сервера, а не проблема с моим кодом. Я буду держать вас в курсе, ребята.

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Вам немного не хватает обработки ошибок.

Во-первых, когда возникает ошибка, ОСТАНОВИТЕ, что вы делаете. Прямо сейчас вы не останавливаетесь, вы просто переходите к следующему вызову API, как будто ошибки не было.

Во-вторых, ваша обработка ошибок на connect() неверна. connect() возвращает 0 в случае успеха и -1 в случае неудачи, но вы проверяете его возвращаемое значение для != 1, поэтому вы будете обрабатывать успехи и неудачи одинаково.

Попробуйте вместо этого:

static SOCKET establishconn(const char *addr, u_short port)
{
    SOCKET commsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (commsock == INVALID_SOCKET)
        return INVALID_SOCKET;

    //OutputDebugStringA(addr);

    SOCKADDR_IN sockaddr = {};
    sockaddr.sin_family = AF_INET;
    sockaddr.sin_port = htons(port);
    sockaddr.sin_addr.s_addr = inet_addr(addr);

    if (sockaddr.sin_addr.s_addr == INADDR_NONE)
    {
        struct hostent *host = gethostbyname(addr);
        if (!host)
        {
            closesocket(commsock);
            return INVALID_SOCKET;
        }
        sockaddr.sin_addr.s_addr = *((u_long*) host->h_addr);
    }

    if (connect(commsock, (SOCKADDR &sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
    {
        closesocket(commsock);
        return INVALID_SOCKET;
    }

    return commsock;
}

Тогда вы можете сделать это:

WSAStartup(...);
...
SOCKET maincommsock = establishconn("127.0.0.1", 69);
if (maincommsock != INVALID_SOCKET)
{
    ...
    closesocket(maincommsock);
}
...
WSACleanup();
0 голосов
/ 10 января 2019

Для сокетов Беркли требуется, чтобы адрес и информация о порте были представлены в порядке сетевых байтов. Winsock следует этому API:

Все данные в структуре SOCKADDR_IN, за исключением семейства адресов, должны указываться в сетевом порядке байтов (big-endian).
Центр разработки Windows

Используйте htons() для преобразования значения порта с хоста в сетевой порядок байтов.

sockaddr.sin_port = htons(69);

inet_addr() уже возвращает значение в сетевом порядке байтов.

...