青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

大龍的博客

常用鏈接

統計

最新評論

send或者write socket遭遇SIGPIPE信號(轉)

當服務器close一個連接時,若client端接著發數據。根據TCP協議的規定,會收到一個RST響應,client再往這個服務器發送數據時,系統會發出一個SIGPIPE信號給進程,告訴進程這個連接已經斷開了,不要再寫了。

又或者當一個進程向某個已經收到RST的socket執行寫操作是,內核向該進程發送一個SIGPIPE信號。該信號的缺省學位是終止進程,因此進程必須捕獲它以免不情愿的被終止。


根據信號的默認處理規則SIGPIPE信號的默認執行動作是terminate(終止、退出),所以client會退出。若不想客戶端退出可以把 SIGPIPE設為SIG_IGN

如:signal(SIGPIPE, SIG_IGN);
這時SIGPIPE交給了系統處理。

服務器采用了fork的話,要收集垃圾進程,防止僵尸進程的產生,可以這樣處理:
signal(SIGCHLD,SIG_IGN);
交給系統init去回收。
這里子進程就不會產生僵尸進程了。


在linux下寫socket的程序的時候,如果嘗試send到一個disconnected socket上,就會讓底層拋出一個SIGPIPE信號。
這個信號的缺省處理方法是退出進程,大多數時候這都不是我們期望的。因此我們需要重載這個信號的處理方法。調用以下代碼,即可安全的屏蔽SIGPIPE:
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigaction( SIGPIPE, &sa, 0 );

signal設置的信號句柄只能起一次作用,信號被捕獲一次后,信號句柄就會被還原成默認值了。
sigaction設置的信號句柄,可以一直有效,值到你再次改變它的設置。

struct sigaction action;
action.sa_handler = handle_pipe;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGPIPE, &action, NULL);
void handle_pipe(int sig)
{
        //不做任何處理即可
}

RST的含義為“復位”,它是TCP在某些錯誤情況下所發出的一種TCP分節。有三個條件可以產生RST:

1), SYN到達某端口但此端口上沒有正在監聽的服務器。
2), TCP想取消一個已有連接
3), TCP接收了一個根本不存在的連接上的分節。

1. Connect 函數返回錯誤ECONNREFUSED:
如果對客戶的SYN的響應是RST,則表明該服務器主機在我們指定的端口上沒有進程在等待與之連接(例如服務器進程也許沒有啟動),這稱為硬錯(hard error),客戶一接收到RST,馬上就返回錯誤ECONNREFUSED.

TCP為監聽套接口維護兩個隊列。兩個隊列之和不超過listen函數第二個參數backlog。

當 一個客戶SYN到達時,若兩個隊列都是滿的,TCP就忽略此分節,且不發送RST.這個因為:這種情況是暫時的,客戶TCP將重發SYN,期望不久就能在 隊列中找到空閑條目。要是TCP服務器發送了一個RST,客戶connect函數將立即發送一個錯誤,強制應用進程處理這種情況,而不是讓TCP正常的重 傳機制來處理。還有,客戶區別不了這兩種情況:作為SYN的響應,意為“此端口上沒有服務器”的RST和意為“有服務器在此端口上但其隊列滿”的 RST.
Posix.1g允許以下兩種處理方法:忽略新的SYN,或為此SYN響應一個RST.歷史上,所有源自Berkeley的實現都是忽略新的SYN。

2.如果殺掉服務器端處理客戶端的子進程,進程退出后,關閉它打開的所有文件描述符,此時,當服務器TCP接收到來自此客戶端的數據時,由于先前打開的那個套接字接口的進程已終止,所以以RST響應。

經常遇到的問題:
如果不判斷read , write函數的返回值,就不知道服務器是否響應了RST, 此時客戶端如果向接收了RST的套接口進行寫操作時,內核給該進程發一個SIGPIPE信號。此信號的缺省行為就是終止進程,所以,進程必須捕獲它以免不情愿地被終止。

進程不論是捕獲了該信號并從其信號處理程序返回,還是不理會該信號,寫操作都返回EPIPE錯誤。


3. 服務器主機崩潰后重啟
如 果服務器主機與客戶端建立連接后崩潰,如果此時,客戶端向服務器發送數據,而服務器已經崩潰不能響應客戶端ACK,客戶TCP將持續重傳數據分節,試圖從 服務器上接收一個ACK,如果服務器一直崩潰客戶端會發現服務器已經崩潰或目的地不可達,但可能需要比較長的時間; 如果服務器在客戶端發現崩潰前重啟,服務器的TCP丟失了崩潰前的所有連接信息,所以服務器TCP對接收的客戶數據分節以RST響應。

二、關于socket的recv:

對于TCP non-blocking socket, recv返回值== -1,但是errno == EAGAIN, 此時表示在執行recv時相應的socket buffer中沒有數據,應該繼續recv。

【If no messages are available at the socket and O_NONBLOCK is not set on the socket's file descriptor, recv() shall block until a message arrives. If no messages are available at the socket and O_NONBLOCK is set on the socket's file descriptor, recv() shall fail and set errno to [EAGAIN] or [EWOULDBLOCK].】

對于UDP recv 應該一直讀取直到recv()==-1 && errno==EAGAIN,表示buffer中數據包被全部讀取。

 

 


    while(res != 0)
    {
        
//len = recv(sockfd, buff, MAXBUF, 0);


        len =recv(sockfd, buff, 5, 0);
        if(len < 0 ){
            if(errno== EAGAIN){
                printf("RE-Len:%d errno EAGAIN\n", len);
                return 12;
            }

            if (errno == EINTR)

               continue;          
            perror("recv error\n");
            break;
        }elseif(len > 0){
            printf("Recved:%s, and len is:%d \n", buff, len);
            len =send(sockfd, buff, len, 0);/* if the client socket was closed and the socketfd here in kernel has set the status as RST this process will recv a SIGPIPE, and the process will exit if we don't handle it to SIGING */
            if(len < 0){
                perror("send error");
                return-1;
            }
            memset(buff, 0, MAXBUF);
            continue;
        }else{
//==0

            printf("Disconnected by peer!\n");
            res = 0;
        }
    }



外記:
accetp()是慢系統調用,在信號產生時會中斷其調用并將errno變量設置為EINTR,此時應重新調用accept()。
所以使用時應這樣:


 while(1){
  if((connfd =accept(....))==-1 ){
  if(errno== EINTR)
  continue;
  perror("accept()");
  exit(1);
  }


  /* do sth with "connfd" */
  }



signal 與 sigaction 區別:
    signal函數每次設置具體的信號處理函數(非SIG_IGN)只能生效一次,每次在進程響應處理信號時,隨即將信號處理函數恢復為默認處理方式.所以如果想多次相同方式處理某個信號,通常的做法是,在響應函數開始,再次調用signal設置。

int sig_int();//My signal handler

    ...
    signal(SIGINT, sig_int);
    ...

int sig_int()
{

   signal(SIGINT, sig_int);
    ....
}

這種代碼段的一個問題是:在信號發生之后到信號處理程序中調用s i g n a l函數之間有一個
時間窗口。在此段時間中,可能發生另一次中斷信號。第二個信號會造成執行默認動作,而對
中斷信號則是終止該進程。這種類型的程序段在大多數情況下會正常工作,使得我們認為它們
正確,而實際上卻并不是如此。
另一個問題是:在進程不希望某種信號發生時,它不能關閉該信號

sigaction:
1.在信號處理程序被調用時,系統建立的新信號屏蔽字會自動包括正被遞送的信號。因此保證了在處理一個
給定的信號時,如果這種信號再次發生,那么它會被阻塞到對前一個信號的處理結束為止
2.響應函數設置后就一直有效,不會重置
3.對除S I G A L R M以外的所有信號都企圖設置S A _ R E S TA RT標志,于是被這些信號中斷
的系統調用(read,write)都能自動再起動。不希望再起動由S I G A L R M信號中斷的系統調用的原因是希望對I / O操作可以設置時間限制。
 
所以希望能用相同方式處理信號的多次出現,最好用sigaction.信號只出現并處理一次,可以用signal

posted on 2011-11-05 01:13 大龍 閱讀(2304) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            能在线观看的日韩av| 免费观看久久久4p| 久久久综合网| 久久精品国产99| 欧美专区日韩视频| 久久免费99精品久久久久久| 久久久青草婷婷精品综合日韩| 欧美一区二区三区精品电影| 久久久精品网| 欧美国产视频在线| 99国产精品99久久久久久粉嫩| 一区二区三区国产精华| 亚洲一区在线免费观看| 久久国产免费看| 久久综合999| 欧美精品一区在线| 国产精品私房写真福利视频| 亚洲视频狠狠| 欧美在线视频免费播放| 欧美日韩性视频在线| 亚洲黄色av| 欧美a级在线| 久久中文字幕导航| 乱码第一页成人| 久久综合久久综合久久| 亚洲激情在线观看视频免费| 99精品国产福利在线观看免费| 一区二区免费在线观看| 久久国产精品第一页| 欧美大尺度在线| 国产精品久久久久久久久搜平片| 国产一区二区三区精品久久久| 亚洲人体大胆视频| 久久精品女人天堂| 99pao成人国产永久免费视频| 欧美亚洲免费高清在线观看| 欧美激情一区二区三区在线| 国产精品一区二区黑丝| 亚洲欧洲另类国产综合| 欧美一级大片在线免费观看| 亚洲国产二区| 久久精品国产欧美激情| 欧美人牲a欧美精品| 国内精品久久久久影院薰衣草| 99精品视频一区二区三区| 老司机免费视频一区二区三区 | 亚洲无限av看| 免费成人av| 激情成人亚洲| 欧美一区二区国产| 亚洲最黄网站| 欧美日韩国产综合视频在线| 亚洲区国产区| 欧美激情亚洲自拍| 久久免费国产| 在线播放中文字幕一区| 久久精品国产在热久久| 亚洲午夜在线视频| 国产精品久久久一本精品| 亚洲免费av网站| av不卡在线| 久久成人精品无人区| 一本到12不卡视频在线dvd| 另类av导航| 亚洲国产精品成人一区二区 | 99国产精品视频免费观看一公开| 久久亚洲私人国产精品va| aa亚洲婷婷| 亚洲国产精品123| 久久精品视频一| 黑人一区二区三区四区五区| 久久精品1区| 久久国产成人| 亚洲国产精品一区二区尤物区| 欧美不卡视频一区发布| 免费成人毛片| 一区二区三区高清视频在线观看| 亚洲人www| 国产精品久久久久aaaa樱花| 欧美一区二区三区婷婷月色 | 91久久黄色| 欧美日韩一区二区三区高清| 亚洲欧美日韩综合国产aⅴ| 亚洲欧美第一页| 狠狠色丁香婷综合久久| 欧美 日韩 国产一区二区在线视频 | 99riav久久精品riav| 国产精品成人一区二区三区吃奶| 亚洲永久视频| 久久精品男女| 亚洲桃花岛网站| 欧美在线亚洲| 9i看片成人免费高清| 午夜在线视频观看日韩17c| 亚洲国产第一页| 亚洲一区久久久| 亚洲日本成人在线观看| 亚洲午夜久久久久久尤物| 激情欧美丁香| 亚洲视频一区在线观看| 樱桃成人精品视频在线播放| 亚洲乱码国产乱码精品精可以看| 国产精品视频午夜| 亚洲电影在线观看| 国产精品一香蕉国产线看观看| 牛牛国产精品| 国产麻豆综合| 99成人在线| 亚洲激情网站| 欧美在线观看你懂的| 亚洲视频一区在线| 免费欧美在线| 久久综合狠狠| 国产精品美女xx| 亚洲国产婷婷| 激情久久五月| 香蕉成人久久| 午夜视频在线观看一区| 欧美极品在线视频| 免费黄网站欧美| 国产一区二区三区无遮挡| 一本高清dvd不卡在线观看| 91久久精品美女| 亚洲大胆人体在线| 国产美女精品视频| 亚洲老司机av| 亚洲日本在线视频观看| 久久久伊人欧美| 久久精品亚洲国产奇米99| 欧美色图五月天| 亚洲精品女人| 在线观看免费视频综合| 性伦欧美刺激片在线观看| 亚洲欧美日韩一区二区三区在线观看 | 午夜影院日韩| 国产精品入口麻豆原神| 亚洲色在线视频| 99视频有精品| 欧美色大人视频| 亚洲一区亚洲| 久久精品国产一区二区三| 国产亚洲欧美一区二区三区| 亚洲欧美日韩综合国产aⅴ| 香蕉久久夜色精品国产使用方法| 欧美性一区二区| 亚洲永久视频| 久久精品久久综合| 夜夜嗨av一区二区三区网站四季av | 国产精品国产一区二区| 99这里只有精品| 亚洲综合久久久久| 国产视频丨精品|在线观看| 欧美自拍偷拍午夜视频| 免费欧美在线视频| 亚洲精品国产精品乱码不99| 欧美精品成人91久久久久久久| 亚洲美女在线看| 性久久久久久久久| 在线观看不卡av| 欧美a一区二区| 一区二区三区日韩欧美精品| 久久精品道一区二区三区| 亚洲国产精品一区二区第一页 | 亚洲日本中文字幕| 欧美日韩小视频| 欧美一区二区三区久久精品茉莉花 | 黄色另类av| 欧美日本二区| 羞羞视频在线观看欧美| 欧美国产视频在线| 久久久久一区二区三区| 亚洲人体大胆视频| 欧美精品在欧美一区二区少妇| 亚洲欧洲日夜超级视频| 亚洲一区二区在线看| 国产一区视频观看| 免费欧美网站| 亚洲一区综合| 欧美电影免费观看高清完整版| 在线视频免费在线观看一区二区| 国产一区二区三区自拍| 欧美国产91| 久久国产福利国产秒拍| 99国产精品久久久久老师| 久久在线免费视频| 羞羞色国产精品| av不卡在线| 亚洲黄一区二区三区| 国产欧美91| 欧美视频精品在线观看| 久久综合网色—综合色88| 亚洲一区二区三区四区五区黄| 亚洲国产一区二区在线| 久久人人爽爽爽人久久久| 亚洲综合色激情五月| 亚洲欧洲精品一区二区三区不卡 | 亚洲国产一区二区三区高清| 久久综合九色欧美综合狠狠| 欧美亚洲视频| 亚洲欧美激情精品一区二区|