即使添加新的防火墙规则后连接仍被拒绝

标签 c unix firewall

我正在尝试连接到我从另一个远程设备创建的本地 UNIX 服务器。服务器已启动并监听我指定的端口。我还添加了一个新的防火墙规则来打开该端口,但我的客户端仍然无法连接。它显示错误连接被拒绝

这是我的服务器代码

int main() {
  int fd, i,svclient,rval,msg;
  int clients[10], num_clients;
  fd_set read_set,write_set;
  char buf[100];

  struct sockaddr_in addr;

  if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket error");
    exit(-1);
  }


  bzero((char *) &addr, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(4001);

  //strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
  //strcpy(addr.sun_path, NAME);

  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
    perror("bind error");
    exit(-1);
  }
  printf("Bind complet...\n");

  if (listen(fd, 20) == -1) {
    perror("listen error");
    exit(-1);
  }

  num_clients = 0;
  int size = sizeof(fd);

   while (1) {

    int clientfd;
    struct sockaddr_in client_addr;
    int addrlen=sizeof(client_addr);
    FD_ZERO(&read_set);
    FD_SET(fd, &read_set);

    for (i = 0; i < num_clients; i++) { //at first this part will not excute
      FD_SET(clients[i], &read_set);
    }

    select(fd + num_clients + 1, &read_set, NULL, NULL, NULL);


    if (FD_ISSET(fd, &read_set)) {
      if ( (clients[num_clients++] = accept(fd,(struct sockaddr*)&client_addr,&addrlen)) == -1) {
        perror("accept error");
        continue;
      }
      /*printf("incoming message..................... !\n \n");*/
      printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
    }


    for (i = 0; i < num_clients; i++) {

      if (FD_ISSET(clients[i], &read_set)) {
        msg = read(clients[i], buf, sizeof(buf));
        if(msg > 0){
          buf[msg] = 0;
          int savedclnt = clients[i];
          printf("%s \n \n", buf);

          /*for(int p=0;p<num_clients;p++)
          {
            if( clients[p]!= savedclnt){
              write(clients[p],buf,msg);
            }

          }*/
        }

      }

    }
  }
}

和我的客户

    int main( )
{   

    struct uci_context *uci;
    uci = uci_init();
    int sockfd;
    int ret;
    struct sockaddr_in dest;
    struct addrinfo hint, *res = NULL;
    struct hostent *host;
    char *hostip;
    char *string;



    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
        puts("Unble to create socket");
        exit(1);
    }

    hostip = ucix_get_option(uci, "pack_mon", "pack_monitoring", "address");
    string = ucix_get_option(uci, "pack_mon", "pack_monitoring", "port");

    bzero(&dest, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_port = htons(atoi(string));

    memset(&hint, '\0', sizeof hint);
    hint.ai_family = PF_UNSPEC;
    hint.ai_flags = AI_NUMERICHOST;

    printf(" %s- %s\n", hostip, string );



    if(isdigit(hostip[0])){
        ret = getaddrinfo(hostip, NULL, &hint, &res);// this is more efficient than inet_addr

        if (ret) {

            exit(1);
        }
    }else if( (host = gethostbyname(hostip)) != 0){

        memcpy((char*)&dest.sin_addr , (char*)host->h_addr , (sizeof dest.sin_addr)+1);

    }else{

        exit(1);
        printf("cannot resolve ip address");
    }  


    if ( connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0 )
    {

        perror("ERROR Connecting" );
        exit(1);
    }else{

        printf("Port number %s is open.....\n",string);
    }


    char *message;
    message = "help";
    write(sockfd,message,strlen(message));


    close(sockfd);
    freeaddrinfo(res);
    return 0;
}

防火墙规则

sudo iptables -I 输入 -p tcp --dport 4001 -j 接受

错误是:

192.168.10.155-4001

连接错误:连接被拒绝

此日志来自此代码:

printf("%s- %s\n", 主机IP, 字符串);

perror("连接错误");

退出(1);

最佳答案

您的客户端没有代码来指定它想要连接的 IP 地址。所有可以做到这一点的代码都已被注释掉。

更新:现在您的错误在这里:

    strncpy((char*)&dest.sin_addr , (char*)host->h_addr , sizeof dest.sin_addr);

strncpy 函数仅适用于 C 风格字符串。您需要使用 memcpy 或类似的东西。如果除最后一个八位字节(按网络字节顺序)以外的任何八位字节为零,则只会复制 IP 地址的一部分。

更新:现在您的错误在这里:

    printf("%d\n", connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0);
    perror("hmmmm" );
    exit(1);

这将调用connect,然后调用printf,然后调用perror。问题是,即使成功,对 printf 的调用也可能会修改 errno 。因此,您对 perror 的调用可以打印完全不相关的错误消息。

关于即使添加新的防火墙规则后连接仍被拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43223372/

相关文章:

c - void* 类型转换为 char* 的增量失败

c - 当大的正数相乘时,为什么结果是负数?

linux - 如何在 Linux 命令行上解析 CSV 文件?

java - Spring批处理文件访问问题?

file - 将多个目录中相同类型的所有文件上移一个文件夹

security - 如何同时在 2 个不同的 symfony2 防火墙上进行身份验证?

c - 混合 openssl API 和 BSD sockets API

php - 与本地主机的套接字连接超时

java - 如何指示 Windows 报告我的 Java 应用程序的名称而不是 java.exe

c - 如何使用 FFMPEG 加速时间线清理?