• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

               C++ 技術(shù)中心

               :: 首頁 :: 聯(lián)系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

            鄭重聲明:本BLOG所發(fā)表的原創(chuàng)文章,作者保留一切權(quán)利。必須經(jīng)過作者本人同意后方可轉(zhuǎn)載,并注名作者(天空)和出處(CppBlog.com)。作者Email:coder@luckcoder.com

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評論

            評論排行榜

            在Linux中使用非阻塞的socket的情形下。

            (一)發(fā)送時

              當客戶通過Socket提供的send函數(shù)發(fā)送大的數(shù)據(jù)包時,就可能返回一個EAGAIN的錯誤。該錯誤產(chǎn)生的原因是由于send 函數(shù)中的size變量大小超過了tcp_sendspace的值。tcp_sendspace定義了應(yīng)用在調(diào)用send之前能夠在kernel中緩存的數(shù)據(jù)量。當應(yīng)用程序在socket中設(shè)置了O_NDELAY或者O_NONBLOCK屬性后,如果發(fā)送緩存被占滿,send就會返回EAGAIN的錯誤。

              為了消除該錯誤,有三種方法可以選擇:
              1.調(diào)大tcp_sendspace,使之大于send中的size參數(shù)
              ---no -p -o tcp_sendspace=65536

              2.在調(diào)用send前,在setsockopt函數(shù)中為SNDBUF設(shè)置更大的值

              3.使用write替代send,因為write沒有設(shè)置O_NDELAY或者O_NONBLOCK

            (二)接收時

            接收數(shù)據(jù)時常遇到Resource temporarily unavailable的提示,errno代碼為11(EAGAIN)。這表明你在非阻塞模式下調(diào)用了阻塞操作,在該操作沒有完成就返回這個錯誤,這個錯誤不會破壞socket的同步,不用管它,下次循環(huán)接著recv就可以。對非阻塞socket而言,EAGAIN不是一種錯誤。在VxWorks和Windows上,EAGAIN的名字叫做EWOULDBLOCK。其實這算不上錯誤,只是一種異常而已。

              另外,如果出現(xiàn)EINTR即errno為4,錯誤描述Interrupted system call,操作也應(yīng)該繼續(xù)。

              最后,如果recv的返回值為0,那表明對方已將連接斷開,我們的接收操作也應(yīng)該結(jié)束。

            (三)以下是另一種解釋

            假如發(fā)送端流量大于接收端的流量(意思是epoll所在的程序讀比轉(zhuǎn)發(fā)的socket要快),由于是非阻塞的socket,那么send()函數(shù)雖然返回,但實際緩沖區(qū)的數(shù)據(jù)并未真正發(fā)給接收端,這樣不斷的讀和發(fā),當緩沖區(qū)滿后會產(chǎn)生EAGAIN錯誤(參考man send),同時,不理會這次請求發(fā)送的數(shù)據(jù).所以,

            需要封裝socket_send()的函數(shù)用來處理這種情況,該函數(shù)會盡量將數(shù)據(jù)寫完再返回,返回-1表示出錯。在socket_send()內(nèi)部,當寫緩沖已滿(send()返回-1,且errno為EAGAIN),那么會等待后再重試.這種方式并不很完美,在理論上可能會長時間的阻塞在socket_send()內(nèi)部,但暫沒有更好的辦法.
            這種方法類似于readn和writen的封裝(自己寫過,在《UNIX環(huán)境高級編程》中也有介紹)

            1. size_t socket_send(int sockfd, const char* buffer, size_t buflen)
            2. {
            3. size_t tmp;
            4. size_t total = buflen;
            5. const char *p = buffer;
            6. while(1)
            7. {
            8. tmp = send(sockfd, p, total, 0);
            9. if(tmp < 0)
            10. {
            11. // 當send收到信號時,可以繼續(xù)寫,但這里返回-1.
            12. if(errno == EINTR)
            13. {
            14. return -1;
            15. }
            16. // 當socket是非阻塞時,如返回此錯誤,表示寫緩沖隊列已滿,
            17. // 在這里做延時后再重試.
            18. if(errno == EAGAIN)
            19. {
            20. usleep(1000);
            21. continue;
            22. }
            23. return -1;
            24. }
            25. if((size_t)tmp == total)
            26. {
            27. return buflen;
            28. }
            29. total -= tmp;
            30. p += tmp;
            31. }
            32. return tmp;
            33. }

            posted on 2013-07-01 18:53 C++技術(shù)中心 閱讀(12630) 評論(0)  編輯 收藏 引用 所屬分類: Linux 編程
            精品久久久久久99人妻| 久久午夜夜伦鲁鲁片免费无码影视| 久久久久亚洲av成人网人人软件 | 色偷偷91久久综合噜噜噜噜| 一级做a爰片久久毛片毛片| 久久精品国产99久久无毒不卡| 亚洲国产精品久久久久网站| 亚洲第一极品精品无码久久| 狠狠久久综合| 久久99国产精一区二区三区| 久久精品国产99久久久古代 | 久久久精品国产sm调教网站| 久久无码人妻精品一区二区三区 | 久久精品国产99久久久香蕉| 狠狠综合久久综合88亚洲| 国产精品伊人久久伊人电影| 久久大香香蕉国产| 一本色道久久HEZYO无码| 久久精品成人影院| 国产精品永久久久久久久久久 | 99久久精品费精品国产一区二区| 人妻精品久久久久中文字幕| 久久夜色精品国产亚洲| 久久发布国产伦子伦精品| 亚洲欧美日韩久久精品第一区| 久久精品中文字幕第23页| 色综合久久久久| 青青青国产精品国产精品久久久久 | 欧美黑人又粗又大久久久| 精品伊人久久久| 99久久做夜夜爱天天做精品| 亚洲性久久久影院| 日韩久久久久中文字幕人妻| 四虎国产精品成人免费久久| 久久只有这里有精品4| 亚洲国产视频久久| 狠狠色婷婷久久综合频道日韩 | 无码日韩人妻精品久久蜜桃| 国色天香久久久久久久小说| 日韩av无码久久精品免费| 久久精品国产亚洲av日韩|