Получение частичных данных из неблокирующего сокета - PullRequest
0 голосов
/ 31 декабря 2018

Я пишу http-сервер с TCP-сокетами на C. По какой-то причине я получаю частичные данные, даже если я вызываю read в таком цикле, как это.

size_t data_len = 0;
while (auto len = read(sock, buf + data_len, read_buffer_size)) {
  if (len < 0) {
    if(errno == EWOULDBLOCK) {
      break;
    }
  }
  data_len += len;
}

Используемые опции сокетов:

setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *) &new_buf_size, sizeof(new_buf_size));
setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *) &new_buf_size, sizeof(new_buf_size));
setsockopt(sock, SOL_SOCKET, SO_DONTROUTE, (void *) &turn_on, sizeof(turn_on));
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &turn_on, sizeof(turn_on));
setsockopt(sock, SOL_SOCKET, SOCK_NONBLOCK, (void *) &turn_on, sizeof(turn_on));
int flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | O_NONBLOCK);

Есть идеи, что я делаю не так?

1 Ответ

0 голосов
/ 31 декабря 2018

Вы устанавливаете его как неблокирующее, а затем не продолжаете чтение, когда оно блокируется ... так что остальные ваши данные поступают позже, но вы уже вне цикла.Важно помнить, что TCP является потоком байтов, и нет никакой корреляции между количеством байтов, отправленных в каждом вызове записи, и количеством байтов, прочитанных при каждом вызове чтения, за исключением того, что они в конечном итоге (учитывая бесконечное время) будут одинаковыми.Вы не даете это бесконечное время.

Удалите оператор break, и вы увидите, что вы получите все свои данные (хотя тогда ваш цикл никогда не закончится).Вам нужно определить протокол, чтобы вы знали, сколько данных ожидать.

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