日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

recv 和 send 阻塞和非阻塞的区别

發(fā)布時(shí)間:2024/10/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 recv 和 send 阻塞和非阻塞的区别 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

答案

深入說(shuō)明

在 epoll 中的應(yīng)用

總結(jié)

拓展


答案

  • 阻塞,事情干不完就不要回來(lái)了!
  • 非阻塞,能干多少就是多少,趕緊回來(lái)!
  • 深入說(shuō)明

    // 將內(nèi)核接收緩沖區(qū)中的數(shù)據(jù) copy 到應(yīng)用層中用戶的 buffer 中。 int recv(int sockfd, void *buf, size_t len, int flag); // 將應(yīng)用層中用戶的 buffer 中的數(shù)據(jù) copy 到內(nèi)核發(fā)送緩沖區(qū)中。 int send(int sockfd, void *buf, size_t len, int flag);

    1、recv?

    阻塞模式下,如果內(nèi)核的接收緩沖區(qū)中沒有數(shù)據(jù)時(shí),該函數(shù)就會(huì)阻塞。

    非阻塞模式下,如果內(nèi)核的接收緩沖區(qū)中沒有數(shù)據(jù)時(shí),該函數(shù)就會(huì)返回。

    2、send

    阻塞模式下,如果發(fā)送緩沖區(qū)剩余的空間小于要發(fā)送的數(shù)據(jù)的大小,那么該函數(shù)會(huì)阻塞。

    非阻塞模式下,如果發(fā)送緩沖區(qū)剩余的空間大于要發(fā)送的數(shù)據(jù)的大小,那么該函數(shù)會(huì)返回。

    在 epoll 中的應(yīng)用

    1、水平觸發(fā)模式(LT)

    在該模式下,recv 和 send 為阻塞和非阻塞,結(jié)果是一樣的。

    舉 recv 栗子來(lái)說(shuō),因?yàn)樵谠撚|發(fā)模式下,只要內(nèi)核的接收緩沖區(qū)中有數(shù)據(jù),epoll_wait()?函數(shù)都會(huì)返回,這就導(dǎo)致了雖然 recv 是阻塞模式的,但是每次調(diào)用時(shí),內(nèi)核緩沖區(qū)都是有數(shù)據(jù)的,所以不會(huì)導(dǎo)致 recv 阻塞。當(dāng)然了,當(dāng) recv 時(shí)是非阻塞的,就更不會(huì)造成阻塞情況了。同理,對(duì)于 send 也是一樣的。

    2、邊沿觸發(fā)模式(LT)

    在該模式下,recv 和 send 需要為非阻塞模式,不然就會(huì)有問(wèn)題。

    還是舉 recv 栗子來(lái)說(shuō),因?yàn)樵谠撃J较?#xff0c;內(nèi)核的接收緩沖區(qū)來(lái)數(shù)據(jù)了,那么 epoll_wait() 函數(shù)就會(huì)返回,但是僅僅返回一次,它可不管你是否在該次中是否完全取走了內(nèi)核接收緩沖區(qū)中的數(shù)據(jù)。

    在上述的前提下,recv 需要一個(gè) while (true) 循環(huán),保證將緩沖區(qū)中的數(shù)據(jù)取空。這就產(chǎn)生了一個(gè)問(wèn)題,因?yàn)榧偃?recv 是阻塞的,那么當(dāng)內(nèi)核緩沖區(qū)中沒有數(shù)據(jù)時(shí),該函數(shù)就會(huì)阻塞,這是致命的,所以 recv 必須是非阻塞的。

    同理,對(duì)于 send 也是一樣的。理想情況時(shí),終于有機(jī)會(huì)向?qū)Χ税l(fā)送數(shù)據(jù)了,一定要將想發(fā)的數(shù)據(jù)發(fā)盡。這就有問(wèn)題了,如果是阻塞的,如果發(fā)到一半,發(fā)送緩沖區(qū)滿了,那么該函數(shù)就阻塞了,實(shí)際上要避免這種情況,所以要將該 send 設(shè)置為非阻塞的。

    總結(jié)

  • 在水平觸發(fā)模式下,recv 和 send 阻塞和非阻塞模式均可。

  • 在邊沿觸發(fā)模式下,recv 和 send 必須為非阻塞模式。

  • 拓展

    1、將socket設(shè)置為非阻塞模式的方法。(socket設(shè)置為非阻塞的,recv 和 send 要設(shè)置為非阻塞的)

    int flags = fcntl(sockfd, F_GETFL, 0); //獲取文件的flags值。fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); //設(shè)置成非阻塞模式; int n = recv(fd, pbuff, kBuffLen, MSG_DONTWAIT);

    ?2、將socket設(shè)置為阻塞模式的方法。

    int flags = fcntl(sockfd, F_GETFL, 0); //獲取文件的flags值。fcntl(sockfd, F_SETFL, flags | ~O_NONBLOCK); //設(shè)置成阻塞模式; int n = recv(fd, pbuff, kBuffLen, 0); // flag = 0,默認(rèn)是阻塞的。

    ?

    (SAW:Game Over!)

    總結(jié)

    以上是生活随笔為你收集整理的recv 和 send 阻塞和非阻塞的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。