簡體   English   中英

Linux,C,epoll(),read()數據未完成?

[英]Linux, C, epoll(), read() data incompleted?

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;
  }

在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)) <= 0) {
                  //error
           }
           else
           {
                   //add bytes to total:
                    __sync_fetch_and_add(&(mythreads->total_bytes_transferred), n)    ;
           }

}
        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的epoll

  1. epoll告訴您何時有數據。
  2. 您當時可以閱讀的內容盡可能多。
  3. 您返回到步驟1。
 event.events = EPOLLIN | EPOLLET;

您正在執行邊緣觸發的輪詢。 這意味着您上次讀取的可能不是讀取所有可用數據。 即使有更多數據可用,它也會在讀取64k數據后停止。 但是由於邊緣觸發,輪詢不會再次觸發。 建議刪除EPOLLET

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM