将select()与多客户端多服务器套接字系统一起使用时出现问题

我正在尝试一个FTP客户端,该客户端可以连接到多个服务器(用于错误编码),但是我认为我做错了什么。 当前,我正在使用connect()测试远程服务器以查看它们是否可用。但是,对于所有服务器(无论它们是否可用),select的返回都是正确的。

客户端可以通过配置文件访问服务器ip:port

struct server
{
  char address[13];
  char port[6];
  int status;
  int sd;
};

typedef struct deployment
{
  int n;
  int k;
  unsigned int block_size;
  struct server server_list[MAX_SERVERS];
} Config;

示例config.txt

3
2
4096
127.0.0.1:13567
127.0.0.1:13568
127.0.0.1:13569

Here, I a loop through n servers and try to connect. Then, have select handle the rest of the program. However, select is returning true for all ports if I use &write_fds and returning the OPPOSITE (i.e all unavailable ports) using &read_fds. I suspect using connect is incorrect and I need to getsockopt? I am really not sure about what needs to be done here or what would be a best practice. Picture of output In this example, I only have 1 server running so the other 2 connect calls return errors yet select doesn't seem to pick up on it.

  for (int i = 0; i < settings->n; i++)
  {
    // get address and port
    int port = atoi(settings->server_list[i].port);
    settings->server_list[i].sd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(settings->server_list[i].address);
    server_addr.sin_port = htons(port);
    //connect to server
    settings->server_list[i].status = connect(settings->server_list[i].sd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (settings->server_list[i].status < 0)
    {
      printf("Error: %s (Errno:%d)\n", strerror(errno), errno);
    }
    max_sd = max(max_sd, settings->server_list[i].sd);
  }
  while (1)
  {
    FD_ZERO(&read_fds);
    FD_ZERO(&write_fds);
    for (int i = 0; i < settings->n; i++)
    {
      FD_SET(settings->server_list[i].sd, &read_fds);
      FD_SET(settings->server_list[i].sd, &write_fds);
    }
    select(max_sd + 1, &read_fds, NULL, NULL, NULL);
    select(max_sd + 1, NULL, &write_fds, NULL, NULL);

    // LIST_REQUEST
    if (packet->type == (unsigned char)0xA1)
    {
      for (int i = 0; i < settings->n; i++)
      {
        if (FD_ISSET(settings->server_list[i].sd, &write_fds))
        {
          printf("SELECTED:\n");
          printf("Address: %s\t", settings->server_list[i].address);
          printf("Port: %s\t", settings->server_list[i].port);
          printf("Sd: %d\t", settings->server_list[i].sd);
          printf("Connection Status: %d\n", settings->server_list[i].status);
        }
      }
    }
    // GET_REQUEST
    if (packet->type == (unsigned char)0xB1)
    {
      printf("GET REQUEST!\n");
    }
    // PUT_REQUEST
    if (packet->type == (unsigned char)0xC1)
    {
      printf("PUT REQUEST!\n");
    }
    exit(0);
  }

If anyone could shed some light on what I need to be doing it would be greatly appreciated. I've tried to research as best I can including this post: Using select() for non-blocking sockets to connect always returns 1 but still don't understand what I need to do given my circumstances. Thanks so much.

评论