[問題] socket程式的SIGPIPE問題

看板Linux作者 (Neko)時間10年前 (2013/09/10 17:32), 編輯推噓1(1020)
留言21則, 5人參與, 最新討論串1/1
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是否已經壞掉了 求助各為了 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.118.127.111

09/10 18:07, , 1F
man 2 select
09/10 18:07, 1F

09/10 20:31, , 2F
我個人印象卡住的話要解的問題是blocking/nonblocking
09/10 20:31, 2F

09/10 20:32, , 3F
SIGPIPE只是其中一個要處理的問題,好像還要注意errno
09/10 20:32, 3F

09/10 20:34, , 4F
如果在solaris上的話errno又有thread safe的問題
09/10 20:34, 4F

09/10 20:35, , 5F
總之我記得上述曾經google過的keyword,但最後我放棄了~XD
09/10 20:35, 5F

09/10 20:48, , 6F
libevent~
09/10 20:48, 6F

09/10 20:58, , 7F
1F是正解,用select直接解決所有問題
09/10 20:58, 7F

09/10 20:58, , 8F
其它方法不是不好,是沒有select這麼全面又易寫
09/10 20:58, 8F

09/10 23:08, , 9F
可是我現在用的就是select的方法耶
09/10 23:08, 9F

09/10 23:11, , 10F
send用的是send(fd, &buf, len, MSG_NOSIGNAL);
09/10 23:11, 10F

09/10 23:11, , 11F
用MSG_NOSIGNAL這個flag是否會造成甚麼副作用呢
09/10 23:11, 11F

09/10 23:13, , 12F
你有根據 writefds 的 fd 是 FD_ISSET 再寫入嗎?
09/10 23:13, 12F

09/10 23:14, , 13F
those in writefds will be watched to see if a write
09/10 23:14, 13F

09/10 23:14, , 14F
will not block
09/10 23:14, 14F

09/11 14:07, , 15F
我對於writefds沒有先FD_ISSET耶 因為FD_ISSET的功能
09/11 14:07, 15F

09/11 14:07, , 16F
不是用來檢查"這個fd裡面是否有資料要讀取"的意思嗎?
09/11 14:07, 16F

09/11 14:08, , 17F
所以我對於發送給client端訊息的時候 沒有先FD_ISSET
09/11 14:08, 17F

09/11 14:09, , 18F
因為我的client端只有"正常斷線"的時候可以讀取到長度0
09/11 14:09, 18F

09/11 14:09, , 19F
其他時候都不會傳送資料的
09/11 14:09, 19F

09/11 15:57, , 20F
我不是有推一段 man select 2 的英文片斷嗎?
09/11 15:57, 20F

09/12 16:26, , 21F
昨天我知道是因為send函式造成的block了
09/12 16:26, 21F
文章代碼(AID): #1IBkSmgA (Linux)