C ++ - bind () не работает - PullRequest
0 голосов
/ 11 июня 2019

Я пытаюсь научиться работать в сети на C ++, и я пытаюсь настроить простую демонстрацию, где я открываю TCP-сервер на порту 5000, а затем сразу же закрываю его.Это мой код:

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>

int main()
{
    int port = 5000;
    std::cout << "Port: " << port << "\n";
    int socketdesc = socket(SOCK_STREAM, AF_INET, 0);

    if (socketdesc == 0)
    {
        std::cout << "Failed to create socket description.\n";
        return 1;
    }

    int opt = 1;

    if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
               &opt, sizeof(opt)))
    {
        std::cout << "Failed to attach socket.\n";
        return 1;
    }

    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);

    if (bind(socketdesc, (struct sockaddr *)&address,
         sizeof(address)) < 0)
    {
        std::cout << "Failed to bind socket!\n";
        return 1;
    }

    std::cout << "Listening with protocol TCP on port" << port << ".\n";

    if (listen(socketdesc, 3) < 0)
    {
        std::cout << "Failed to listen!\n";
        return 1;
    }

    if (shutdown(socketdesc, SHUT_RDWR) < 0)
    {
        std::cout << "Failed to close socket!\n";
        return 1;
    }

    std::cout << "TCP test succeeeded.\n";
    return 0;
}

Я получаю сообщение об ошибке при попытке привязать сокет к порту 5000. Что не так с настройкой порта TCP-сервера?

PS: чточто это за бит (я слежу за учебником и смотрю документацию по sys / socket одновременно)?

Ответы [ 2 ]

1 голос
/ 12 июня 2019

В вашем коде есть несколько ошибок, прежде чем вы достигнете bind():

int socketdesc = сокет (SOCK_STREAM, AF_INET, 0);

У вас есть первые 2 значения параметров в обратном направлении, вызов должен выглядеть следующим образом:

int socketdesc = socket(AF_INET, SOCK_STREAM, 0);

if (socketdesc == 0)

socket() возвращает -1 при ошибке, а не 0.

if (setsockopt (socketdesc, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, & opt, sizeof (opt)))

setsockopt() также возвращает -1 при ошибке.

Но что более важно, вы не можете объединить несколько опций сокетов в одном вызове, как это. Вам нужно звонить setsockopt() для каждого варианта в отдельности:

if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
...

if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0)
...

С учетом сказанного попробуйте следующее:

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main()
{
    int port = 5000;
    std::cout << "Port: " << port << "\n";

    int socketdesc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (socketdesc == -1)
    {
        std::cout << "Failed to create socket descriptor. " << strerror(errno) << "\n";
        return 1;
    }

    int opt = 1;

    if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
    {
        std::cout << "Failed to set SO_REUSEADDR option. " << strerror(errno) << "\n";
        return 1;
    }

    if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0)
    {
        std::cout << "Failed to set SO_REUSEPORT option. " << strerror(errno) << "\n";
        return 1;
    }

    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);

    if (bind(socketdesc, (struct sockaddr *)&address, sizeof(address)) < 0)
    {
        std::cout << "Failed to bind socket! " << strerror(errno) << "\n";
        return 1;
    }

    std::cout << "Listening with protocol TCP on port" << port << ".\n";

    if (listen(socketdesc, 3) < 0)
    {
        std::cout << "Failed to listen on socket! " << strerror(errno) << "\n";
        return 1;
    }

    if (shutdown(socketdesc, SHUT_RDWR) < 0)
    {
        std::cout << "Failed to close socket! " << strerror(errno) << "\n";
        return 1;
    }

    close(socketdesc);

    std::cout << "TCP test succeeeded.\n";
    return 0;
}
0 голосов
/ 11 июня 2019

Я оставлю этот ответ здесь, даже если в этот раз это было не так. Я думаю, что это все еще реальный случай, и кто-то ищет ответы на сайте, может оценить это.

(реальный ответ для кода выше был в комментариях)


Вам необходимо закрыть сокет, вы не делали этого при каждом сбое. Он останется открытым и не позволит вам снова привязаться к нему, даже если процесс завершится.

Если это не так, возможно, у вас есть другая программа, использующая порт. Попробуйте изменить номер порта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...