socket程式的SIGPIPE問題 - Linux

Table of Contents


hi

請問各位
我的程式會不斷的發送資料給client端
使用的是TCP/IP連線

但是我實驗發現 如果client端未依正常程序結束(例如跳電,拔網路線)...等
server端大約過5~6秒就會卡住
所有資料都送不出去了 這時唯有結束server端程式重啟才行

查了一下google 有提到SIGPIPE 說是在send的過程中如果client端斷線或是RST
這時候系統會拋出一個SIGPIPE的signal
預設的處理方式是結束terminal 這當然不是我想要的

然後有說可以用
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigaction( SIGPIPE, &sa, 0 );

用signal的函式讓SIGPIPE交給SIG_IGN處理
然後有提到sigaction函式是使用一次就永久有效
如果用signal(SIGPIPE, SIG_IGN); 則是只有一次效果

但是經過我交叉測試 不管我怎麼設 只要我手動把client端網路關掉
大約經過5~6秒後 server端就一定會卡住 動彈不得
新資料送不出去 client連線也連不進來


請問我該怎麼處理比較好呢
理想狀態是如果SIGPIPE 我就把那個connection close掉
至少server端系統要持續進行 不能終止或是卡住
只是要先偵測到SIGPIPE 因為靠send函式的return值無法觀察出這個connection是否已經壞掉了



求助各為了 謝謝











--

All Comments

Ivy avatarIvy2013-09-14
man 2 select
Margaret avatarMargaret2013-09-16
我個人印象卡住的話要解的問題是blocking/nonblocking
Gary avatarGary2013-09-16
SIGPIPE只是其中一個要處理的問題,好像還要注意errno
Irma avatarIrma2013-09-19
如果在solaris上的話errno又有thread safe的問題
Rachel avatarRachel2013-09-20
總之我記得上述曾經google過的keyword,但最後我放棄了~XD
Andrew avatarAndrew2013-09-24
libevent~
Catherine avatarCatherine2013-09-28
1F是正解,用select直接解決所有問題
其它方法不是不好,是沒有select這麼全面又易寫
Kama avatarKama2013-09-30
可是我現在用的就是select的方法耶
Charlotte avatarCharlotte2013-10-04
send用的是send(fd, &buf, len, MSG_NOSIGNAL);
用MSG_NOSIGNAL這個flag是否會造成甚麼副作用呢
Blanche avatarBlanche2013-10-07
你有根據 writefds 的 fd 是 FD_ISSET 再寫入嗎?
Wallis avatarWallis2013-10-11
those in writefds will be watched to see if a write
will not block
Caitlin avatarCaitlin2013-10-15
我對於writefds沒有先FD_ISSET耶 因為FD_ISSET的功能
不是用來檢查"這個fd裡面是否有資料要讀取"的意思嗎?
Elma avatarElma2013-10-16
所以我對於發送給client端訊息的時候 沒有先FD_ISSET
Heather avatarHeather2013-10-17
因為我的client端只有"正常斷線"的時候可以讀取到長度0
其他時候都不會傳送資料的
David avatarDavid2013-10-20
我不是有推一段 man select 2 的英文片斷嗎?
Hedda avatarHedda2013-10-20
昨天我知道是因為send函式造成的block了