看板 Linux 關於我們 聯絡資訊
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
Spig:man 2 select 09/10 18:07
Kuster:我個人印象卡住的話要解的問題是blocking/nonblocking 09/10 20:31
Kuster:SIGPIPE只是其中一個要處理的問題,好像還要注意errno 09/10 20:32
Kuster:如果在solaris上的話errno又有thread safe的問題 09/10 20:34
Kuster:總之我記得上述曾經google過的keyword,但最後我放棄了~XD 09/10 20:35
dou0228:libevent~ 09/10 20:48
bitlife:1F是正解,用select直接解決所有問題 09/10 20:58
bitlife:其它方法不是不好,是沒有select這麼全面又易寫 09/10 20:58
neko0624:可是我現在用的就是select的方法耶 09/10 23:08
neko0624:send用的是send(fd, &buf, len, MSG_NOSIGNAL); 09/10 23:11
neko0624:用MSG_NOSIGNAL這個flag是否會造成甚麼副作用呢 09/10 23:11
bitlife:你有根據 writefds 的 fd 是 FD_ISSET 再寫入嗎? 09/10 23:13
bitlife:those in writefds will be watched to see if a write 09/10 23:14
bitlife: will not block 09/10 23:14
neko0624:我對於writefds沒有先FD_ISSET耶 因為FD_ISSET的功能 09/11 14:07
neko0624:不是用來檢查"這個fd裡面是否有資料要讀取"的意思嗎? 09/11 14:07
neko0624:所以我對於發送給client端訊息的時候 沒有先FD_ISSET 09/11 14:08
neko0624:因為我的client端只有"正常斷線"的時候可以讀取到長度0 09/11 14:09
neko0624:其他時候都不會傳送資料的 09/11 14:09
bitlife:我不是有推一段 man select 2 的英文片斷嗎? 09/11 15:57
neko0624:昨天我知道是因為send函式造成的block了 09/12 16:26