<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux內(nèi)核中send與recv函數(shù)詳解

          linux內(nèi)核中send與recv函數(shù)詳解

          作者: 時(shí)間:2016-11-22 來源:網(wǎng)絡(luò) 收藏

          1.簡介

          本文引用地址:http://www.ex-cimer.com/article/201611/320010.htm
          [plain]view plaincopy
          print?
          1. #include
          2. ssize_trecv(intsockfd,void*buff,size_tnbytes,intflags);
          3. ssize_tsend(intsockfd,constvoid*buff,size_tnbytes,intflags);

          • send和recv的前3個(gè)參數(shù)等同于read和write;
          • flags參數(shù)值為0或:

          flags說明recvsend
          MSG_DONTROUTE繞過路由表查找
          MSG_DONTWAIT僅本操作非阻塞
          MSG_OOB    發(fā)送或接收帶外數(shù)據(jù)
          MSG_PEEK  窺看外來消息
          MSG_WAITALL  等待所有數(shù)據(jù)

          2. send解析

          • sockfd:指定發(fā)送端套接字描述符。
          • buff: 存放要發(fā)送數(shù)據(jù)的緩沖區(qū)
          • nbytes: 實(shí)際要改善的數(shù)據(jù)的字節(jié)數(shù)
          • flags: 一般設(shè)置為0

          1) send先比較發(fā)送數(shù)據(jù)的長度nbytes和套接字sockfd的發(fā)送緩沖區(qū)的長度,如果nbytes > 套接字sockfd的發(fā)送緩沖區(qū)的長度, 該函數(shù)返回SOCKET_ERROR。

          2) 如果nbtyes <= 套接字sockfd的發(fā)送緩沖區(qū)的長度,那么send先檢查協(xié)議是否正在發(fā)送sockfd的發(fā)送緩沖區(qū)中的數(shù)據(jù),如果是就等待協(xié)議把數(shù)據(jù)發(fā)送完,如果協(xié)議還沒有開始發(fā)送sockfd的發(fā)送緩沖區(qū)中的數(shù)據(jù)或者sockfd的發(fā)送緩沖區(qū)中沒有數(shù)據(jù),那么send就比較sockfd的發(fā)送緩沖區(qū)的剩余空間和nbytes。

          3) 如果 nbytes > 套接字sockfd的發(fā)送緩沖區(qū)剩余空間的長度,send就一起等待協(xié)議把套接字sockfd的發(fā)送緩沖區(qū)中的數(shù)據(jù)發(fā)送完。

          4) 如果 nbytes < 套接字sockfd的發(fā)送緩沖區(qū)剩余空間大小,send就僅僅把buf中的數(shù)據(jù)copy到剩余空間里(注意:并不是send把套接字sockfd的發(fā)送緩沖區(qū)中的數(shù)據(jù)傳到連接的另一端的,而是協(xié)議傳送的。send僅僅是把buf中的數(shù)據(jù)copy到套接字sockfd的發(fā)送緩沖區(qū)的剩余空間里)。

          5) 如果send函數(shù)copy成功,就返回實(shí)際copy的字節(jié)數(shù),如果send在copy數(shù)據(jù)時(shí)出現(xiàn)錯(cuò)誤,那么send就返回SOCKET_ERROR;如果在等待協(xié)議傳送數(shù)據(jù)時(shí)網(wǎng)絡(luò)斷開,send函數(shù)也返回SOCKET_ERROR。

          6) send函數(shù)把buff中的數(shù)據(jù)成功copy到sockfd的發(fā)送緩沖區(qū)的剩余空間后它就返回了,但是此時(shí)這些數(shù)據(jù)并不一定馬上被傳到連接的另一端。如果協(xié)議在后續(xù)的傳送過程中出現(xiàn)網(wǎng)絡(luò)錯(cuò)誤的話,那么下一個(gè)socket函數(shù)就會(huì)返回SOCKET_ERROR(每一個(gè)除send的socket函數(shù)在執(zhí)行的最開始總要先等待套接字的發(fā)送緩沖區(qū)中的數(shù)據(jù)被協(xié)議傳遞完畢才能繼續(xù),如果在等待時(shí)出現(xiàn)網(wǎng)絡(luò)錯(cuò)誤那么該socket函數(shù)就返回SOCKET_ERROR)。

          7) 在unix系統(tǒng)下,如果send在等待協(xié)議傳送數(shù)據(jù)時(shí)網(wǎng)絡(luò)斷開,調(diào)用send的進(jìn)程會(huì)接收到一個(gè)SIGPIPE信號(hào),進(jìn)程對(duì)該信號(hào)的處理是進(jìn)程終止。

          2.recv解析

          • sockfd: 接收端套接字描述符
          • buff: 用來存放recv函數(shù)接收到的數(shù)據(jù)的緩沖區(qū)
          • nbytes: 指明buff的長度
          • flags: 一般置為0

          1) recv先等待sockfd的發(fā)送緩沖區(qū)的數(shù)據(jù)被協(xié)議傳送完畢,如果協(xié)議在傳送sock的發(fā)送緩沖區(qū)中的數(shù)據(jù)時(shí)出現(xiàn)網(wǎng)絡(luò)錯(cuò)誤,那么recv函數(shù)返回SOCKET_ERROR。

          2) 如果套接字sockfd的發(fā)送緩沖區(qū)中沒有數(shù)據(jù)或者數(shù)據(jù)被協(xié)議成功發(fā)送完畢后,recv先檢查套接字sockfd的接收緩沖區(qū),如果sockfd的接收緩沖區(qū)中沒有數(shù)據(jù)或者協(xié)議正在接收數(shù)據(jù),那么recv就一起等待,直到把數(shù)據(jù)接收完畢。當(dāng)協(xié)議把數(shù)據(jù)接收完畢,recv函數(shù)就把sockfd的接收緩沖區(qū)中的數(shù)據(jù)copy到buff中(注意:協(xié)議接收到的數(shù)據(jù)可能大于buff的長度,所以在這種情況下要調(diào)用幾次recv函數(shù)才能把sockfd的接收緩沖區(qū)中的數(shù)據(jù)copy完。recv函數(shù)僅僅是copy數(shù)據(jù),真正的接收數(shù)據(jù)是協(xié)議來完成的)。

          3) recv函數(shù)返回其實(shí)際copy的字節(jié)數(shù),如果recv在copy時(shí)出錯(cuò),那么它返回SOCKET_ERROR。如果recv函數(shù)在等待協(xié)議接收數(shù)據(jù)時(shí)網(wǎng)絡(luò)中斷了,那么它返回0。

          4) 在unix系統(tǒng)下,如果recv函數(shù)在等待協(xié)議接收數(shù)據(jù)時(shí)網(wǎng)絡(luò)斷開了,那么調(diào)用 recv的進(jìn)程會(huì)接收到一個(gè)SIGPIPE信號(hào),進(jìn)程對(duì)該信號(hào)的默認(rèn)處理是進(jìn)程終止。



          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();