Может подключиться к моей программе через локальный хост, но не может подключиться с помощью других компьютеров в сети - PullRequest
0 голосов
/ 21 декабря 2018

Я написал программу для игры в сети (или, возможно, через Интернет).Я написал это, используя C.

Программа прекрасно работает, когда я запускаю хост и клиент на одной машине.Однако я не могу установить соединение, когда оно работает на двух разных машинах.

Я использую Ubuntu 18.04 LTS на обоих компьютерах.Я не понимаю, почему это имеет значение, но один подключен к маршрутизатору через Ethernet.Другой подключен к сети без проводов.ufw verbose показывает, что брандмауэр неактивен на обоих компьютерах.

То, что я уже пробовал:

  1. Добавление имени сервера к хосту в / ect / hosts вместо вводаIP-адрес в аргумент программы (работает в обоих направлениях на локальной машине, не работает ни в одной из сетей).
  2. Добавление исключения брандмауэра в брандмауэр маршрутизатора.
  3. Перенаправление порта, который я использую (5001) на моем маршрутизаторе.
  4. nmap к ip компьютера, на котором запущен хост, показывает, что порт 5001 / tcp открыт со службой «commplex-link»
  5. Может подключаться к хосту через удаленный компьютер по сети.

void network_host(void) {

    int sockfd, newsockfd, portno, clilen;
    struct sockaddr_in serv_addr, cli_addr;
    int n;
    struct game *main_game = createboard();

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (sockfd < 0) {
        perror("On opening socket ERROR: \n");
        exit(1);
    }

    memset(&serv_addr, 0, sizeof serv_addr );
    portno = 5001;

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof serv_addr ) < 0 ) {
        perror("On socket binding ERROR: \n");
        exit(1);
    }

    printf("Waiting for opponent . . .\n");
    listen(sockfd, 1);
    clilen = sizeof cli_addr;
    memset(&cli_addr, 0, clilen);

    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 

    if (newsockfd < 0) {
        perror("On accepting connection ERROR: \n");
        exit(1);
    }

    printf("Opponent connected!\n");

    while (main_game->play) {
            printboard(main_game);
            entermove(main_game, GAME_HOST, newsockfd);
            checkwin(main_game);
    }
}

void network_client(char *host_name) {

    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    struct game *main_game = createboard();

    portno = 5001;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (sockfd < 0) {
        perror("Error opening socket");
        exit(1);
    }

    server = gethostbyname(host_name);

    if (server == NULL) {
        fprintf(stderr, "Error, no such host.\n");
        exit(0);
    }

    memset((char *) &serv_addr, 0, sizeof serv_addr);
    serv_addr.sin_family = AF_INET;
    memcpy((char *)server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length);
    serv_addr.sin_port = htons(portno);

    if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Error connecting.\n");
        exit(1);
    }

    while (main_game->play) {
        printboard(main_game);
        entermove(main_game, GAME_CLIENT, sockfd);
        checkwin(main_game);
    }
}

Так как эта программа будет работать при подключении к localhost, nmap показывает, что порт открыт, и я могу удаленно войти в программу, я вообще не могу.куда идти дальше.

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

Я готов вернуться через эти шаги (возможно, некоторые из них я сделал только наполовину правильно).Но также готовы принять другие возможные идеи.

1 Ответ

0 голосов
/ 21 декабря 2018

В этой строке ваша проблема:

memcpy((char *)server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length);

memcpy определяется как получение пункта назначения, источника и размера ... так что вы копируете вещи не так, как serverгде адресПоменяйте местами, и все будет работать нормально ...

memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);

Вам также не нужно ничего разыгрывать, поскольку вначале эти два аргумента для memcpy должны быть void *, а не char *и во-вторых, указатели автоматически конвертируются в void *

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