Только первые несколько многопоточных клиентов могут прочитать ответ из сокета - PullRequest
0 голосов
/ 03 апреля 2019

Я строю клиент-серверную программу на C, используя сокеты. И мой клиент, и мой сервер используют фиксированное количество потоков для работы. Сначала я протестировал очень мало клиентских и серверных потоков (5 и 3), и все, казалось, работало нормально. Но теперь я попытался увеличить число клиентских потоков до 500 (в то время как количество серверных потоков остается на 3), но все ломается. Клиент первой сотни или около того может отправить свой запрос и получить ответ, но остальные ничего не получают с сервера.

Я работаю над подсистемой Windows Debian, если это что-то изменит.

Я также попытался увеличить число потоков сервера до 300, но проблема все еще возникает.

Вот мой (очень) упрощенный код.

Клиентская нить

  int client_socket= socket(AF_INET, SOCK_STREAM, 0);
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(2018);
  addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  memset(&addr.sin_zero, 0, sizeof(addr.sin_zero));
  connect(client_socket, (struct sockaddr *) &addr, sizeof(addr));

  int response;
  int cid = 1;

  send(client_socket, &cid, sizeof(int), 0);

  int len = read_socket(socket, &response, sizeof(int), 1000);
  if (len == 0) {
      printf("No response");
  } else {
      printf("Response");
  }
  close(client_socket);

Серверная нить

int socket_fd, cid, len;
while (1)
  {
    socket_fd =
        accept(socket_fd, (struct sockaddr *)&thread_addr, &socket_len);
    if (socket_fd> 0) {
        int cid;
        int len = read_socket(socket_fd, &cid, sizeof(cid), 1000);
        if (len == 0) {
          printf("Nothing");
        }
        send(socket_fd, &cid, sizeof(int),0);
        close(socket_fd);
    }
  }

А вот и моя вспомогательная функция read_socket()

ssize_t read_socket(int sockfd, void *buf, size_t obj_sz, int timeout) {
  int ret;
  int len = 0;

  struct pollfd fds[1];
  fds->fd = sockfd;
  fds->events = POLLIN;
  fds->revents = 0;

  do {
    // wait for data or timeout
    ret = poll(fds, 1, timeout);

    if (ret > 0) {
      if (fds->revents & POLLIN) {
          ret = recv(sockfd, (char*)buf + len, obj_sz - len, 0);
          if (ret < 0) {
            // abort connection
            perror("recv()");
            return -1;
          }
          len += ret;
      }
    } else {
      // TCP error or timeout
      if (ret < 0) {
        perror("poll()");
      }
      break;
    }
  } while (ret != 0 && len < obj_sz);
  return ret;
}

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

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