【问题标题】:Client cannot connect to server on a different machine -- solved客户端无法连接到另一台机器上的服务器 - 已解决
【发布时间】:2020-06-09 08:31:37
【问题描述】:

原来问题不在我这边……我使用的 Linux 服务器的防火墙拒绝连接……

我正在编写一个客户端/服务器模型,我的目标是客户端和服务器可以在不同的机器上运行,但是,我的客户端中的 connect() 总是返回 -1。 Ping 适用于两台机器之间的两个方向。 代码在同一台机器上运行。

client.c

    int fd;
    int PORT;
    char IP[20];
    struct hostent *server;
    printf("Enter Port Number: \n");
    scanf("%d", &PORT);
    printf("Enter IP Address: \n");
    scanf("%s", IP);
    server = gethostbyname(IP);

    socklen_t len;
    struct sock_opts *ptr;
    struct sockaddr_in serv_addr;
    fd = socket(AF_INET, SOCK_STREAM, 0);
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(IP);
    serv_addr.sin_port = htons(PORT);

    connect(fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)); //connection timed out

服务器.c

 int sockfd, newsockfd, clilen, n;
 int PORT;
 printf("Enter Port Number: \n");
 scanf("%d", &PORT);
 struct sockaddr_in serv_addr, cli_addr;
 char buffer[128];

 sockfd = socket(AF_INET, SOCK_STREAM, 0);
 bzero((char *) &serv_addr, sizeof(serv_addr));

 serv_addr.sin_family = AF_INET;
 serv_addr.sin_addr.s_addr = INADDR_ANY;
 serv_addr.sin_port = htons(PORT); 
 bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr));
 listen(sockfd,5);
 clilen = sizeof(cli_addr);
 newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

输出: ./客户

Enter Port Number:
5544
Enter IP Address
192.168.1.56
ERROR: Connection timed out

./服务器

Enter Port Number:
5544
Server will then time out because client is not able to connect.

【问题讨论】:

  • 致电perror 获取更详细的错误描述。如果您需要进一步的帮助,请提供minimal verifiable example 并提供您的确切输入。
  • 我修改了问题。

标签: c networking network-programming


【解决方案1】:

我认为有两件事可以帮助你。

首先,您可以使用一些工具,如 wireshark 或 tcpdump 来查看套接字的运行情况。

其次,connect返回值可以给出很多信息,可以看this

下次记得给个完整的代码,能说明你的问题。

【讨论】:

  • 哦,我没有贴代码,让我修改问题。
  • 应该是评论吧?
  • @Gerhardh 在他编辑他的问题时,我编辑了我的答案。而且我的旧答案与他的旧问题相对匹配,我认为这不仅仅是评论。
  • "connection timed out" 是错误消息..显示服务器没有响应。我会看看 Wireshark 和 tcpdump,谢谢
【解决方案2】:

我不确定服务器是如何超时的。如果没有中断并且套接字被阻塞,如果服务器没有接收到任何连接,它应该永远在accept() 暂停。快速查看并根据您报告的行为,服务器代码首先终止,因此客户端变得无连接。

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

这是您的服务器出错的地方。在将 clilen 传递给 accept() 之前,您没有初始化它。在调用 accept()

之前,您的服务器代码可能已经预料到了这一点
/* .... */

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

/* .... */

【讨论】:

  • 嘿,我忘了贴初始化clilen的代码,好眼力!
  • 但这不是问题的根源,正如我所说,我的代码在单台机器上工作,所以套接字的设置应该没有问题。而且是我的客户端connect()先返回错误,服务器一直处于连接状态。
  • @Ashley 它甚至没有在不同的机器上运行一次,或者当您尝试重复运行服务器代码时它失败了?因为端口不会在代码终止时立即释放并且您没有检查 bind(),即使 bind() 失败的服务器仍然继续运行并且操作系统将临时端口分配给未绑定的套接字
  • 它从来没有奏效。我的每一步都有错误消息,所以我会知道绑定之类的事情是否失败,我没有在此处发布调试代码。每次重新运行程序时,我都会使用不同的端口..
猜你喜欢
  • 1970-01-01
  • 2012-10-15
  • 2012-10-28
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多