从非阻塞套接字接收部分数据

时间:2018-12-31 16:16:40

标签: c sockets

我正在用C语言编写带有TCP套接字的http服务器。由于某种原因,即使我像这样循环调用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 :(得分:2)

您正在将其设置为非阻塞,然后在阻塞时不再继续读取...,因此其余数据稍后会传入,但您已经不在循环中了。重要的是要记住,TCP是字节流,并且在每个写调用中发送的字节数与在每个读调用中读取的字节数之间没有相关性,只是它们最终(给定的无限时间)是相同的。您没有给它无限的时间。

删除break语句,您将看到将获取所有数据(尽管循环永远不会结束)。您需要定义一个协议,以便知道需要多少数据。