关于epoll中的read函数说明
生活随笔
收集整理的這篇文章主要介紹了
关于epoll中的read函数说明
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
之前寫過一篇關于Linux下面采用epoll設計服務器應用程序的文章,時隔很久了,最近發現一個問題,是關于read函數讀取報文時候問題,這里提出來。 epoll并不像windows下的完成端口那樣,可以通知用戶此次事件(收數據或者發數據)的數據量有多少,因此在讀取數據的時候就比較麻煩了,因為epoll通知你只是有新數據到達了,并不告訴你有多少,因此需要應用層運用循環不斷的收數據,知道結束。結合下面的源代碼進行分析一下。 while(m_RcvedLen < TotalSize) {?
????if((Rcv = read(m_sClient, m_Buffer, (TotalSize - m_RcvedLen))) < 0) {?
??????if(EAGAIN == errno) {?
????????break;?
??????}?
??????else {?
????????perror("read fail");?
????????close(m_sClient);?
????????return -1;?
??????}?
????}?
????else if(0 == Rcv){?
??????close(m_sClient);?????????
??????return -2;?
????}?
????else {?
??????m_RcvedLen += Rcv;?
????}?
??} 上面的代碼是先讀報頭,后讀報體的。原來是直接讀,給read函數的第三個參數一個很大的值,知道read函數返回錯誤EAGAIN才表示沒有數據可以讀了,但是這樣會出現一個問題,當客戶端發送了數據之后就直接關閉socket,此時服務端第一包讀取正常,這時循環繼續讀下一報,此時read函數不會返回EAGAIN,而是返回0,表示客戶端已經關閉連接了。所以,在服務端讀取的時候,一定要先讀報文,從報文中獲得此次報文的大小,然后依次來作為接收結束的判斷條件。這樣上層就可以根據read函數的返回值不同,區分出(1)還有報文可讀(2)報文已經讀完(3)對方關閉socket三種情況了。
本文轉自jazka 51CTO博客,原文鏈接:http://blog.51cto.com/jazka/371899,如需轉載請自行聯系原作者
????if((Rcv = read(m_sClient, m_Buffer, (TotalSize - m_RcvedLen))) < 0) {?
??????if(EAGAIN == errno) {?
????????break;?
??????}?
??????else {?
????????perror("read fail");?
????????close(m_sClient);?
????????return -1;?
??????}?
????}?
????else if(0 == Rcv){?
??????close(m_sClient);?????????
??????return -2;?
????}?
????else {?
??????m_RcvedLen += Rcv;?
????}?
??} 上面的代碼是先讀報頭,后讀報體的。原來是直接讀,給read函數的第三個參數一個很大的值,知道read函數返回錯誤EAGAIN才表示沒有數據可以讀了,但是這樣會出現一個問題,當客戶端發送了數據之后就直接關閉socket,此時服務端第一包讀取正常,這時循環繼續讀下一報,此時read函數不會返回EAGAIN,而是返回0,表示客戶端已經關閉連接了。所以,在服務端讀取的時候,一定要先讀報文,從報文中獲得此次報文的大小,然后依次來作為接收結束的判斷條件。這樣上層就可以根據read函數的返回值不同,區分出(1)還有報文可讀(2)報文已經讀完(3)對方關閉socket三種情況了。
本文轉自jazka 51CTO博客,原文鏈接:http://blog.51cto.com/jazka/371899,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的关于epoll中的read函数说明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JQuery中操作Css样式的方法
- 下一篇: 解决ntp的错误 no server s