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

Linux,C,epoll(),read()数据未完成?,c,linux,sockets,epoll,C,Linux,Sockets,Epoll,Linux,C.以下问题仅在使用epoll()时发生。如果在服务器套接字上使用select(),则不会丢失数据 ============================= 更新: 我在read()中收到errno=11(重试)。 我需要继续还是中断while循环 ============================= 我有客户端,10次发送1280 K数据(每次发送128K数据) 在服务器端,使用epoll()监视传入的数据 收到通知后,我使用以下代码读取数据: nbytes = Nread

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 < 1) {
                          printf("errno: %d\n", errno);
                          break;  //I do received 2 errors of Try Again. How to try again?
                  }

                  left -= r;
                  buffer += r;
          }
          printf("=> done, %ld\n", total - left);
          return count - left;
  }
===============

更新:

如果使用此代码读取所有数据,则不会丢失字节。但是性能很差:

 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 }
36整数读取(整数fd,字符*缓冲区)
37 {
38 ssize_t计数=0,字节=0;
39
40而(1){
41字节=读取(fd、缓冲区、sizeof(缓冲区));
42如果(字节<1)
43次中断;
44计数+=字节;
45         }
46返回计数;
47 }
===================================

EPOLL()
efd=epoll\u create1(0);
event.data.fd=侦听器\u fd;
event.events=EPOLLIN | EPOLLET;
epoll\u ctl(efd、epoll\u ctl\u ADD、侦听器\u fd和事件);
而(1){
n_fds=epoll_wait(efd,events,MAX_epoll_events,-1);
对于(i=0;i
通过返回您的epoll循环

        data: 60734  //??? why I am not able to read all 65536 bytes?
因为他们还没有收到

我认为您可能会错过如何使用
epoll
进行非阻塞I/O的大图

  • epoll
    告诉您何时有数据
  • 那时你尽可能多地阅读
  • 返回到步骤1
  • 通过返回您的epoll循环

            data: 60734  //??? why I am not able to read all 65536 bytes?
    
    因为他们还没有收到

    我认为您可能会错过如何使用
    epoll
    进行非阻塞I/O的大图

  • epoll
    告诉您何时有数据
  • 那时你尽可能多地阅读
  • 返回到步骤1
  • 您正在执行边缘触发轮询。这意味着您的上次读取可能没有读取所有可用数据。即使有更多可用数据,它也会在读取64k数据后停止。但由于边缘触发,轮询将不会再次触发。建议删除
    EPOLLET



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

    ,因为128K数据不是在单个数据块中发送的。显然您有总计60734字节的块到达(接近)同时触发
    epoll
    ,然后在更多数据到达之前有足够的延迟,您的循环在此期间运行。在这种情况下,我最终可以从客户端接收所有数据。但当前情况是,我接收的数据少于客户端发送的数据。例如,客户端发送1310720字节,但我只接收1301118字节。如果您认为这是case然后显示其余代码。特别是调用
    epoll
    Nread
    的代码(在完整上下文中)。很可能您只是没有读取所有数据或错误地解释结果。例如,当您读取的字节数少于需要跟踪的全部字节数时,后续读取需要考虑到这一点。传输层是什么?通过本地以太网的TCP?通过Internet的TCP?本地环回?Unix socket?您正处于合理阻塞I/O和合理非阻塞I/O之间的一个奇怪的中间地带。选择一个并坚持下去。因为128K不是在一个块中发送的。显然,您已经收到了总计60734字节的块(几乎)同时触发
    epoll
    ,然后在更多数据到达之前有足够的延迟,您的循环在此期间运行。在这种情况下,我最终可以从客户端接收所有数据。但当前情况是,我接收的数据少于客户端发送的数据。例如,客户端发送1310720字节,但我只接收1301118字节。如果您认为这是case然后显示其余代码。特别是调用
    epoll
    Nread
    的代码(在完整上下文中)。很可能您只是没有读取所有数据或错误地解释结果。例如,当您读取的字节数少于需要跟踪的全部字节数时,后续读取需要考虑到这一点。传输层是什么?通过本地以太网的TCP?通过Internet的TCP?本地环回?Unix socket?您处于某种奇怪的中间地带,介于可感知的阻塞I/O和可感知的非阻塞I/O之间。选择一个并坚持它。我有epoll()在一个while循环中等待通知。网络是40G以太网。我等待了10秒,仍然没有收到所有字节。@SimonXiao然后你需要等待更多数据,读取这些数据,并将其添加到缓冲区。但是如果你丢失了一些数据,代码中显然有一个bug。你在计算有多少数据丢失了吗您总共收到了吗?@SimonXiao您总共发送了多少字节?您总共收到了多少字节?@David Schwartz,我发送了1310720字节,但收到了1174846字节。输出在最上面的帖子中进行了更新。@SimonXiao我打赌您计算发送或接收字节的代码是错误的。您是否对所有调用的返回值求和
    Nread
    ?您是否考虑到对发送函数的调用可能不会发送您要求它们发送的所有字节,并且您必须查看返回值?我确实在while循环中使用了epoll()来等待通知。网络是40G以太网。我等待了10秒,但仍然没有收到通知
            break;  //I do received 2 errors of Try Again. How to try again?
    
            data: 60734  //??? why I am not able to read all 65536 bytes?
    
     event.events = EPOLLIN | EPOLLET;