Linux,C,epoll(),read()数据未完成?

Linux,C。下面的问题只发生在使用epoll()。 如果我在服务器套接字上使用select(),则不会丢失数据。

=============================

更新:我在read()中收到了errno = 11(再试一次)。 我需要继续,还是打破while循环?

=============================

我有客户端,10次发送1280 K数据(每次发送128K数据);

我有服务器端,使用epoll()来监视传入的数据。

收到通知后,我使用下面的代码来读取数据:

nbytes = Nread(current_fd, buffer, bytes_to_be_read); int Nread(int fd, char *buffer, size_t count) { ssize_t r; size_t left = count; printf("===>\n"); while (left > 0){ r = read(fd, buffer, left); printf("data: %ld\n", r); if (r  done, %ld\n", total - left); return count - left; } 

在Nread中,我期望读取bytes_to_be_read(65536)个字节并返回。

但是,当运行该工具时,我发现服务器端只是收到这样的东西。 看起来我在某些情况下没有从缓冲区读取所有数据。 为什么?

 1===> data: 65536 => done, 65536 2===> data: 65536 => done, 65536 3===> data: 60734 data: 4802 => done, 65536 4===> data: 55934 data: -1 errno: 11 => done, 55934 //data is not enough. the missing part should come soon. but why I am not notified? 5===> data: 60736 data: 4800 => done, 65536 6===> data: 65536 => done, 65536 7===> data: 65536 => done, 65536 8===> data: 65536 => done, 65536 9===> data: 65536 => done, 65536 10===> data: 65536 => done, 65536 11===> data: 65536 => done, 65536 12===> data: 65536 => done, 65536 13===> data: 65536 => done, 65536 14===> data: 65536 => done, 65536 15===> data: 65536 => done, 65536 16===> data: 65536 => done, 65536 17===> data: 65536 => done, 65536 18===> data: 65536 => done, 65536 19===> data: 65536 => done, 65536 

===============

更新:

如果我使用此代码读取所有数据,则没有字节丢失。 但表现不好:

  36 int read_all(int fd, char *buffer) 37 { 38 ssize_t count = 0, bytes = 0; 39 40 while(1){ 41 bytes = read(fd, buffer, sizeof(buffer)); 42 if (bytes < 1) 43 break; 44 count += bytes; 45 } 46 return count; 47 } 

===================================

EPOLL()

 efd = epoll_create1 (0); event.data.fd = listener_fd; event.events = EPOLLIN | EPOLLET; epoll_ctl(efd, EPOLL_CTL_ADD, listener_fd, &event); while (1){ n_fds = epoll_wait (efd, events, MAX_EPOLL_EVENTS, -1); for (i = 0; i < n_fds; i++){ ........... if (islistener) { ..... //handle new connections } else{ bzero(buffer, recv_buf_size); if ((n= Nread(fd, buffer, recv_buf_size)) total_bytes_transferred), n) ; } } 

  event.events = EPOLLIN | EPOLLET; 

您正在进行边缘触发轮询。 这意味着您上一次阅读可能无法读取所有可用数据。 它在读取64k数据后停止,即使有更多可用数据。 但由于边缘触发,轮询不会再次触发。 建议删除EPOLLET

  break; //I do received 2 errors of Try Again. How to try again? 

回到你的epoll循环。

  data: 60734 //??? why I am not able to read all 65536 bytes? 

因为他们尚未收到。

我想你可能会错过关于如何使用epoll进行非阻塞I / O的大图。

  1. epoll告诉你什么时候有数据。
  2. 你当时尽可能多地阅读。
  3. 你回到第1步。