一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

send返回值

 Frank__Library 2014-05-12

  1. int ret = this->peer().send_n(ack_msg, len, &time_zero_);  
  2.     switch (ret)  
  3.     {  
  4.         case 0:  
  5.             // peer closed  
  6.          
  7.             return -1;  
  8.         case -1:  
  9.             if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINPROGRESS)  
  10.             {  
  11.             //block  
  12.                 return 0;  
  13.             }  
  14.             else  
  15.             {  
  16.                 // abnormal error  
  17.             }  
  18.         default:  
  19.             if (ret != len)  
  20.             {  
  21.                             //no complex  
  22.                 return -1;  
  23.             }  
  24.             break;  
  25. if ((r = write(fd, offset, toSend)) < 0) {  
  26.                 switch (errno) {  
  27.                 case EAGAIN:  
  28.                 case EINTR:  
  29.                     r = 0;  
  30.                     break;  
  31.                 case EPIPE:  
  32.                 case ECONNRESET:  
  33.                     return -2;  
  34.                 default:  
  35.                     log_error_write(srv, __FILE__, __LINE__, "ssd",  
  36.                         "write failed:", strerror(errno), fd);  
  37.                     return -1;  
  38.                 }  
  39.             }  
  40. c->offset += r;  
  41.             cq->bytes_out += r;  
  42.             if (c->offset == (off_t)c->mem->used - 1) {  
  43.                 chunk_finished = 1;  
  44.             }  

 

在Unix系統(tǒng)下,如果send 、 recv 、 write在等待協(xié)議傳送數(shù)據(jù)時(shí) , socket shutdown,調(diào)用send的進(jìn)程會(huì)接收到一個(gè)SIGPIPE信號(hào),進(jìn)程對(duì)該信號(hào)的默認(rèn)處理是進(jìn)程終止。 此種情況 應(yīng)用就很難查 處理進(jìn)程為什么退出。

 

SIGPIPE 信號(hào):

對(duì)一個(gè)已經(jīng)收到FIN包的socket調(diào)用read方法, 如果接收緩沖已空, 則返回0, 這就是常說(shuō)的表示連接關(guān)閉. 但第一次對(duì)其調(diào)用write方法時(shí), 如果發(fā)送緩沖沒(méi)問(wèn)題, 會(huì)返回正確寫入(發(fā)送). 但發(fā)送的報(bào)文會(huì)導(dǎo)致對(duì)端發(fā)送RST報(bào)文, 因?yàn)閷?duì)端的socket已經(jīng)調(diào)用了close, 完全關(guān)閉, 既不發(fā)送, 也不接收數(shù)據(jù). 所以, 第二次調(diào)用write方法(假設(shè)在收到RST之后), 會(huì)生成SIGPIPE信號(hào), 導(dǎo)致進(jìn)程退出 。如果對(duì) SIGPIPE 進(jìn)行忽略處理, 二次調(diào)用write方法時(shí), 會(huì)返回-1, 同時(shí)errno置為SIGPIPE.

處理方法:

在初始化時(shí)調(diào)用 signal(SIGPIPE,SIG_IGN) 忽略該信號(hào)(只需一次) , SIGPIPE交給了系統(tǒng)處理。 此時(shí) send 、 recv write 函數(shù)將返回-1,errno為EPIPE,可視情況關(guān)閉socket或其他處理    

SIGPIPE 被忽略的情況下,如果 服務(wù)器采用了fork的話,要收集垃圾進(jìn)程,防止僵尸進(jìn)程的產(chǎn)生,可以這樣處理:  signal(SIGCHLD,SIG_IGN); 交給系統(tǒng)init去回收。 這樣 子進(jìn)程就不會(huì)產(chǎn)生僵尸進(jìn)程了。

 

ACE中發(fā)送和接收超時(shí)都是基于select的

 

  1. ssize_t  
  2. ACE::send_n_i (ACE_HANDLE handle,  
  3.                const void *buf,  
  4.                size_t len,  
  5.                int flags,  
  6.                const ACE_Time_Value *timeout,  
  7.                size_t *bt)  
  8. {  
  9.   size_t temp;  
  10.   size_t &bytes_transferred = bt == 0 ? temp : *bt;  
  11.   ssize_t n;  
  12.   ssize_t result = 0;  
  13.   int error = 0;  
  14.   int val = 0;  
  15.   ACE::record_and_set_non_blocking_mode (handle, val);  
  16.   for (bytes_transferred = 0;  
  17.        bytes_transferred < len;  
  18.        bytes_transferred += n)  
  19.     {  
  20.       // Try to transfer as much of the remaining data as possible.  
  21.       // Since the socket is in non-blocking mode, this call will not  
  22.       // block.  
  23.       n = ACE_OS::send (handle,  
  24.                         (char *) buf + bytes_transferred,  
  25.                         len - bytes_transferred,  
  26.                         flags);  
  27.       // Check for errors.  
  28.       if (n == 0 ||  
  29.           n == -1)  
  30.         {  
  31.           // Check for possible blocking.  
  32.           if (n == -1 &&  
  33.               (errno == EWOULDBLOCK || errno == ENOBUFS))  
  34.             {  
  35.               // Wait upto <timeout> for the blocking to subside.  
  36.               int rtn = ACE::handle_write_ready (handle,  
  37.                                                  timeout);  
  38.               // Did select() succeed?  
  39.               if (rtn != -1)  
  40.                 {  
  41.                   // Blocking subsided in <timeout> period.  Continue  
  42.                   // data transfer.  
  43.                   n = 0;  
  44.                   continue;  
  45.                 }  
  46.             }  
  47.           // Wait in select() timed out or other data transfer or  
  48.           // select() failures.  
  49.           error = 1;  
  50.           result = n;  
  51.           break;  
  52.         }  
  53.     }  
  54.   ACE::restore_non_blocking_mode (handle, val);  
  55.   if (error)  
  56.     {  
  57.       return result;  
  58.     }  
  59.   else  
  60.     {  
  61.       return ACE_Utils::truncate_cast<ssize_t> (bytes_transferred);  
  62.     }  
  63. }  
  64. int  
  65. ACE::handle_ready (ACE_HANDLE handle,  
  66.                    const ACE_Time_Value *timeout,  
  67.                    int read_ready,  
  68.                    int write_ready,  
  69.                    int exception_ready)  
  70. {  
  71. #if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)  
  72.   ACE_UNUSED_ARG (write_ready);  
  73.   ACE_UNUSED_ARG (exception_ready);  
  74.   struct pollfd fds;  
  75.   fds.fd = handle;  
  76.   fds.events = read_ready ? POLLIN : POLLOUT;  
  77.   fds.revents = 0;  
  78.   int result = ACE_OS::poll (&fds, 1, timeout);  
  79. #else  
  80.   ACE_Handle_Set handle_set;  
  81.   handle_set.set_bit (handle);  
  82.   // Wait for data or for the timeout to elapse.  
  83.   int select_width;  
  84. #  if defined (ACE_WIN32)  
  85.   // This arg is ignored on Windows and causes pointer truncation  
  86.   // warnings on 64-bit compiles.  
  87.   select_width = 0;  
  88. #  else  
  89.   select_width = int (handle) + 1;  
  90. #  endif /* ACE_WIN64 */  
  91.   int result = ACE_OS::select (select_width,  
  92.                                read_ready ? handle_set.fdset () : 0, // read_fds.  
  93.                                write_ready ? handle_set.fdset () : 0, // write_fds.  
  94.                                exception_ready ? handle_set.fdset () : 0, // exception_fds.  
  95.                                timeout);  
  96. #endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */  
  97.   switch (result)  
  98.     {  
  99.     case 0:  // Timer expired.  
  100.       errno = ETIME;  
  101.       /* FALLTHRU */  
  102.     case -1: // we got here directly - select() returned -1.  
  103.       return -1;  
  104.     case 1: // Handle has data.  
  105.       /* FALLTHRU */  
  106.     default: // default is case result > 0; return a  
  107.       // ACE_ASSERT (result == 1);  
  108.       return result;  
  109.     }  

其它lighttpd:

[c-sharp] view plaincopy
  1. // if  (len == 0 || (len < 0 && errno != EAGAIN && errno != EINTR) ) {  
  2. case -1:  
  3.             if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINPROGRESS)  
  4.             {  
  5.                 return 0;  
  6.             }  
  7. if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {  
  8.         switch (errno) {  
  9.         case EAGAIN:  
  10. #if EWOULDBLOCK != EAGAIN  
  11.         case EWOULDBLOCK:  
  12. #endif  
  13.         case EINTR:  
  14.             /* we were stopped _before_ we had a connection */  
  15.         case ECONNABORTED: /* this is a FreeBSD thingy */  
  16.             /* we were stopped _after_ we had a connection */  
  17.             break;  
  18.         case EMFILE:  
  19.             /* out of fds */  
  20.             break;  
  21.         default:  
  22.             log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);  
  23.         }  
  24.         return NULL;  
  25.     }  
  26. fcgi  
  27. if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {  
  28.         if (errno == EINPROGRESS ||  
  29.             errno == EALREADY ||  
  30.             errno == EINTR) {  
  31.             if (hctx->conf.debug > 2) {  
  32.                 log_error_write(srv, __FILE__, __LINE__, "sb",  
  33.                     "connect delayed; will continue later:", proc->connection_name);  
  34.             }  
  35.             return CONNECTION_DELAYED;  
  36.         } else if (errno == EAGAIN) {  
  37.             if (hctx->conf.debug) {  
  38.                 log_error_write(srv, __FILE__, __LINE__, "sbsd",  
  39.                     "This means that you have more incoming requests than your FastCGI backend can handle in parallel."  
  40.                     "It might help to spawn more FastCGI backends or PHP children; if not, decrease server.max-connections."  
  41.                     "The load for this FastCGI backend", proc->connection_name, "is", proc->load);  
  42.             }  
  43.             return CONNECTION_OVERLOADED;  
  44.         } else {  
  45.             log_error_write(srv, __FILE__, __LINE__, "sssb",  
  46.                     "connect failed:",  
  47.                     strerror(errno), "on",  
  48.                     proc->connection_name);  
  49.             return CONNECTION_DEAD;  
  50.         }  
  51.     }  

 

 

 

 

    if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 ||
                fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0)

 

 

EAGAIN、EWOULDBLOCK、EINTR與非阻塞 長(zhǎng)連接

EWOULDBLOCK用于非阻塞模式,不需要重新讀或者寫

EINTR指操作被中斷喚醒,需要重新讀/寫

在Linux環(huán)境下開發(fā)經(jīng)常會(huì)碰到很多錯(cuò)誤(設(shè)置errno),其中EAGAIN是其中比較常見的一個(gè)錯(cuò)誤(比如用在非阻塞操作中)。
從字面上來(lái)看,是提示再試一次。這個(gè)錯(cuò)誤經(jīng)常出現(xiàn)在當(dāng)應(yīng)用程序進(jìn)行一些非阻塞(non-blocking)操作(對(duì)文件或socket)的時(shí)候。例如,以 O_NONBLOCK的標(biāo)志打開文件/socket/FIFO,如果你連續(xù)做read操作而沒(méi)有數(shù)據(jù)可讀。此時(shí)程序不會(huì)阻塞起來(lái)等待數(shù)據(jù)準(zhǔn)備就緒返 回,read函數(shù)會(huì)返回一個(gè)錯(cuò)誤EAGAIN,提示你的應(yīng)用程序現(xiàn)在沒(méi)有數(shù)據(jù)可讀請(qǐng)稍后再試。
又例如,當(dāng)一個(gè)系統(tǒng)調(diào)用(比如fork)因?yàn)闆](méi)有足夠的資源(比如虛擬內(nèi)存)而執(zhí)行失敗,返回EAGAIN提示其再調(diào)用一次(也許下次就能成功)。
Linux - 非阻塞socket編程處理EAGAIN錯(cuò)誤
在linux進(jìn)行非阻塞的socket接收數(shù)據(jù)時(shí)經(jīng)常出現(xiàn)Resource temporarily unavailable,errno代碼為11(EAGAIN),這是什么意思?
這表明你在非阻塞模式下調(diào)用了阻塞操作,在該操作沒(méi)有完成就返回這個(gè)錯(cuò)誤,這個(gè)錯(cuò)誤不會(huì)破壞socket的同步,不用管它,下次循環(huán)接著recv就可以。 對(duì)非阻塞socket而言,EAGAIN不是一種錯(cuò)誤。在VxWorks和Windows上,EAGAIN的名字叫做EWOULDBLOCK。
另外,如果出現(xiàn)EINTR即errno為4,錯(cuò)誤描述Interrupted system call,操作也應(yīng)該繼續(xù)。
最后,如果recv的返回值為0,那表明連接已經(jīng)斷開,我們的接收操作也應(yīng)該結(jié)束。

當(dāng)客戶通過(guò)Socket提供的send函數(shù)發(fā)送大的數(shù)據(jù)包時(shí),就可能返回一個(gè)EGGAIN的錯(cuò)誤。該錯(cuò)誤產(chǎn)生的原因是由于send

函數(shù) 中的size變量大小超過(guò)了tcp_sendspace的值。tcp_sendspace定義了應(yīng)用在調(diào)用send之前能夠在kernel中緩存的數(shù)據(jù) 量。當(dāng)應(yīng)用程序在socket中設(shè)置了O_NDELAY或者O_NONBLOCK屬性后,如果發(fā)送緩存被占滿,send就會(huì)返回EAGAIN的錯(cuò)誤。

為了消除該錯(cuò)誤,有三種方法可以選擇:
1.調(diào)大tcp_sendspace,使之大于send中的size參數(shù)
---no -p -o tcp_sendspace=65536

2.在調(diào)用send前,在setsockopt函數(shù)中為SNDBUF設(shè)置更大的值 

 

1.你自己的緩沖區(qū)滿了,會(huì)返回EAGAIN。

2.你的沒(méi)滿,對(duì)方的緩沖區(qū)滿了,肯定不關(guān)你事,可能會(huì)發(fā)送不成功,但是協(xié)議棧提供的系統(tǒng)調(diào)用,只管數(shù)據(jù)成功從你的緩沖區(qū)發(fā)出去,之后人家因?yàn)榫彌_區(qū)滿收不到數(shù)據(jù),tcp自己有重傳機(jī)制(參考Tcp/ip詳解卷1)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    黄色日韩欧美在线观看| 亚洲欧美中文日韩综合| 国产欧美另类激情久久久| 东京热电东京热一区二区三区| 日韩精品第一区二区三区| 国产超碰在线观看免费| 在线观看视频国产你懂的| 亚洲精品伦理熟女国产一区二区 | 国产精品免费自拍视频| 亚洲人妻av中文字幕| 国产一区二区三区四区中文| 欧美人禽色视频免费看| 日本精品最新字幕视频播放| 精品视频一区二区不卡| 91精品蜜臀一区二区三区| 国产成人在线一区二区三区 | 丰满少妇高潮一区二区| 91精品视频免费播放| 国产精品一级香蕉一区| 久久热在线免费视频精品| 日韩人妻一区二区欧美| 欧美黑人在线一区二区| 亚洲一区二区三在线播放| 欧美一级特黄大片做受大屁股 | 国产欧美性成人精品午夜| 亚洲精品一二三区不卡| 日韩欧美在线看一卡一卡| 国内午夜精品视频在线观看| 精品人妻一区二区三区在线看| 欧美精品亚洲精品日韩专区| 熟女乱一区二区三区四区| 欧美日韩国产综合在线| 欧美一区二区三区性视频| 久久亚洲精品中文字幕| 大香蕉伊人精品在线观看| 日韩在线中文字幕不卡| 欧美特色特黄一级大黄片| 婷婷伊人综合中文字幕| 成人你懂的在线免费视频| 婷婷基地五月激情五月| 翘臀少妇成人一区二区|