可以通过本地主机连接到我的程序,但无法使用网络上的其他计算机进行连接

标签 c sockets

我编写了一个程序来通过网络(或可能是互联网)玩井字游戏。我用 C 编写了这个。

当我在同一台机器上运行主机和客户端时,程序运行得很好。但是,当它在两台不同的计算机上运行时,我无法建立连接。

我在两台计算机上都使用 Ubuntu 18.04 LTS。我不明白为什么这很重要,但一个是通过以太网连接到路由器的。另一个通过无线方式连接到网络。 ufw verbose 显示两台计算机上的防火墙均处于非事件状态。

我已经尝试过的事情:

  1. 将服务器名称添加到/ect/hosts 中的主机,而不是键入 将 IP 地址放入程序参数中(在本地上双向工作) 机,无法通过网络以任何方式工作)。
  2. 向路由器防火墙添加防火墙异常(exception)。
  3. 端口转发我在路由器上使用的端口 (5001)。
  4. nmap 到运行主机的计算机的 IP 显示端口 5001/tcp 已通过服务“complex-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);
    }
}

由于该程序在连接到本地主机时将工作,nmap 显示远程打开的端口,并且我可以远程登录到该程序,所以我根本不知道下一步该去哪里。

在我看来,这不是一个编码错误,因为它在本地工作,但由于我可以远程登录到该程序,所以它似乎不应该是一个网络错误。

我愿意回溯这些步骤(也许其中一些我只做了一半)。但也愿意接受其他可能的想法。

最佳答案

这一行就是你的问题所在

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 *

关于可以通过本地主机连接到我的程序,但无法使用网络上的其他计算机进行连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53886400/

相关文章:

c - 我的代码中有哪些错误?

java - 在使用 Apache 'HttpClient' 的 PUT 操作期间更快地检测中断的连接

java - 即使服务器已启动,如何解决 java net ConnectException 连接被拒绝连接

c - 嵌套时切换大小写

c - 在C中将操作发送到后台

c - epoll 和发送滞后

iphone - 如何在 iOS 上修改数据包的 IP header ?

Java:套接字 - DataStream 真的很慢

java - 实现 Arp 扫描

c - 验证来自另一个函数的数组变量输入