[問題] non-blocking socket問題

看板C_and_CPP作者 (Neko)時間10年前 (2014/01/09 05:24), 編輯推噓7(7033)
留言40則, 8人參與, 最新討論串1/2 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) GCC 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) NO 問題(Question): 各位好 請問我的server程式需要頻繁的呼叫send函式把資料送出去 然後又是一個real-time的系統所以用blocking的socket的話 會慢慢累積delay 最後就是崩潰 資料全部過時 搜尋了一下 應該是要改用non-blocking的socket 於是我用 int flags= fcntl(forwardSockfd, F_GETFL, 0); fcntl(forwardSockfd, F_SETFL, flags | O_NONBLOCK); 這種方式將socket改成non-blocking 請問這樣做的話 我還需要檢查send的return值嗎 目前遇到的問題可能會有: 1. client斷線 造成呼叫send的時候剛好broken pipe 2. client跳電 造成buffer full 要等兩小時後才會time out結束連線 如果我用non-blocking的話 以上兩種問題該如何得知呢 因為blocking socket的時候 還可以看回傳值 測試用non-blocking socket後 回傳值常會變成-1 然後errno是EAGAIN 但是不是很懂意思 所以我是否可直接跳過return值? 感謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.34.7.57

01/09 11:36, , 1F
EAGAIN就是叫你AGAIN啊
01/09 11:36, 1F

01/09 11:37, , 2F
non-blocking就兩種狀況 能馬上給出結果 所以給結果了
01/09 11:37, 2F

01/09 11:37, , 3F
這時跟一般socket沒啥差別 另一種狀況就是還沒結果
01/09 11:37, 3F

01/09 11:38, , 4F
這時就丟出EAGAIN 叫你晚點再來試 看到時會不會有結果
01/09 11:38, 4F

01/09 12:01, , 5F
請問是哪兩種狀況? 那我遇到EAGAIN的時候要什麼時候再回
01/09 12:01, 5F

01/09 12:02, , 6F
來看?下次呼叫send的時候嗎. 所以是不是我遇到EAGAIN就
01/09 12:02, 6F

01/09 12:02, , 7F
不理他就好了
01/09 12:02, 7F

01/09 14:23, , 8F
反正C語言通常return 0以外都是出錯啦
01/09 14:23, 8F

01/09 14:24, , 9F
non-blocking就是用try的 不成功就return err
01/09 14:24, 9F

01/09 14:24, , 10F
不會卡在那邊
01/09 14:24, 10F

01/09 16:23, , 11F
謝謝 server這邊搞定了 卻變成client端收到的資料有問題
01/09 16:23, 11F

01/09 16:24, , 12F
程式跑約0.5秒後 收到的資料欄位會亂掉 跟著程式就掛掉了
01/09 16:24, 12F

01/09 16:24, , 13F
請問會不會是send端的buffer滿了的關係?我該如何除錯呢
01/09 16:24, 13F

01/09 16:31, , 14F
因為資料都是固定長度的 所以欄位會亂掉除了send端的
01/09 16:31, 14F

01/09 16:32, , 15F
buffer overflow外 我想不出其他可能性 :(
01/09 16:32, 15F

01/09 18:34, , 16F
前面 w大的 "C語言通常return 0以外都是出錯" 怎解??
01/09 18:34, 16F

01/09 18:37, , 17F
什麼 open(), send(), printf() ... 大於 0 也都是對啊...
01/09 18:37, 17F

01/09 18:38, , 18F
回原PO, 若是 server client 不同台, 試著抓封包出來看吧...
01/09 18:38, 18F

01/09 18:42, , 19F
或是收送兩端都把資料先 dump 出來, 再做後續處理...
01/09 18:42, 19F

01/09 18:43, , 20F
應該可以協助 debug 看看收送過程發生什麼事...
01/09 18:43, 20F

01/09 19:19, , 21F
我把server端每次send的回傳值印出來 因為長度是固定的
01/09 19:19, 21F

01/09 19:20, , 22F
果然每次都是正確的長度 然後約0.5秒後就會長度變少
01/09 19:20, 22F

01/09 19:20, , 23F
然後client端就爆了 所以應該是buffer的問題囉
01/09 19:20, 23F

01/09 19:21, , 24F
我的資料流量約4xxKB/s 我明天試試看把buffer加大
01/09 19:21, 24F

01/09 19:22, , 25F
不好意思 這是我的第一隻server程式 所以問題比較基本
01/09 19:22, 25F

01/09 20:31, , 26F
buffer加大只會讓你晚幾秒死 不要這樣做
01/09 20:31, 26F

01/09 20:39, , 27F
blocking socket會卡 表示你的頻寬可能撐不住這個流量
01/09 20:39, 27F

01/09 20:40, , 28F
用什麼方式送都一樣沒救
01/09 20:40, 28F

01/09 23:26, , 29F
會python 的話,可以試 twisted
01/09 23:26, 29F

01/10 00:07, , 30F
是喔 可是server跟client的網卡跟線路應該都稱的住這流量
01/10 00:07, 30F

01/10 00:08, , 31F
一秒4xxKB/s而已 我想會不會是send太頻繁(一秒300多次)
01/10 00:08, 31F

01/10 13:32, , 32F
那應該有其他原因讓流量到不了400kB
01/10 13:32, 32F

01/10 17:00, , 33F
server有用fork或pthread處理連線嗎?
01/10 17:00, 33F

01/10 22:43, , 34F
send傳回的值不到buffer的長度不是應該從沒傳完的部分
01/10 22:43, 34F

01/10 22:43, , 35F
開始重新send嗎 OAO...
01/10 22:43, 35F

01/11 02:47, , 36F
幾個問題: (1) server產生資料和client消化資料的速率各如何?
01/11 02:47, 36F

01/11 02:48, , 37F
(2) client收到不完整的資料會如何處理?
01/11 02:48, 37F

01/11 02:51, , 38F
(3) server是否有檢查和處理不完整送出的資料?
01/11 02:51, 38F

01/11 02:54, , 39F
(4) 若是tcp連線, 是否使用了 setsockopt()設定TCP_NODELAY?
01/11 02:54, 39F

01/11 02:58, , 40F
其中 (2) 改為 ...收到不完整/格式不正確的資料...
01/11 02:58, 40F
文章代碼(AID): #1IpS7oXl (C_and_CPP)
文章代碼(AID): #1IpS7oXl (C_and_CPP)