国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux IO函數的使用和區別

2024-06-28 13:19:54
字體:
來源:轉載
供稿:網友
linux IO函數的使用和區別

Linux系統中的IO函數主要有read、write、recv、send、recvmsg、sendmsg、readv、writev,本篇主要介紹他們的使用以及區別。

read函數:

#include <unistd.h>ssize_t read(int fd,void *buf,size_t count);

read函數從文件描述符fd對應的文件中,讀取count字節,放在buf緩沖區。如果count為0,read返回為0,不進行其他操作;如果count的值大于SSIZE_MAX,結果不能預料。在讀取成功的時候,文件對應的讀取位置指針,,向后移動位置,大小為成功讀取的字節數。

如果read執行成功,訪回讀取的字節數;當返回為-1時候,讀取函數有錯誤發生。如果已經達到文件的末尾,返回0;其中,ssize數據類型是不同于int、long類型,它是符號數,具體實現時,可能是int,也可能是long。

write函數:

#include <unistd.h>ssize_t write(int fd,const void *buf,size_t count);

參數含義與read類似。

recv函數:

#include <sys/types.h>#include <sys/socket.h>ssize_t recv(int s,void *buf,size_t len,int flags);

recv函數用于接受數據,該函數從套接字s中接收數據放到緩沖區buf中,buf長度為len,操作的方式由flags指定,第一個參數s是套接字文件描述符,它是由系統調用socket函數返回。第二個參數buf是一個指針,指向接收網絡的緩沖區。第三個參數len表示緩沖區的大小,以字節為單位。第四個參數flags用于設置接收數據的方式:

recv()函數flasgs的值及含義
MSG_DONTWAIT非阻塞,立即返回,不等待
MSG_ERRQUEUE錯誤消息從套接字錯誤隊列中接收
MSG_OOB接收外部數據
MSG_PEEK  查看數據,不進行數據緩沖區的清空
MSG_TRUNC返回所有數據,即使指定的緩沖區過小
MSG_WAITALL等待所有消息

MSG_DONTWAIT:這個標志將單個IO操作設為非阻塞,而不需要在套接字上打開非阻塞標志,執行IO,然后關閉非阻塞標志。

MSG_ERRQUEUE:該錯誤的傳輸依賴于所使用的協議。

MSG_OOB:這個標志可以接收帶外的數據,而不是接收一般數據。

MSG_PEEK:這標志查看可讀的數據,在recv函數執行后,內核不會將這些數據丟棄。

MSG_TRUNC:在接收數據后,如果用戶的緩沖區大小不足以完全復制緩沖區里的數據,則將數據截掉,僅靠復制用戶緩沖區大小的數據,其他的數據將丟棄。

MSG_WAITALL:告訴內核在沒有讀到請求的字節數之前不要讀操作返回。如果系統支持這個標志,可以去掉readn()函數而用下面的替代:

#define readn(fd,ptr,n) recv(fd,ptr,n,MSG_WAITALL).

即使設置了MSG_WAITALL,如果發生以下情況:a撲捉一個信號;b連接終止;c在套接字上發生錯誤,這個函數返回的字節數仍然比請求的少。

當指定MSG_WAITALL標志時,函數會復制與用戶指定的長度相等的數據。如果內核中的數據不能滿足要求,會一直等待到數據足夠的時候才返回。

函數recv()的返回值是成功接收到的字節數,當返回值為-1時錯誤發生。

recv函數errno的值及含義
EAGAIN套接字定義為非阻塞,而操作采用了阻塞方式;或者定義了超時時間到了,而沒有接收到數據
EBADF參數s不是合法的描述符
ECONNREFUSED遠程主機不允許此操作
EFAULT接收緩沖區的指針,在此進程之外
EINTR接收到中斷信號
EINVAL傳遞了不合法的參數
ENOTCONN套接字s表示流式套接字,此套接字沒有連接
ENOTSOCK參數不是套接字描述符

recv()通常用于TCP,UDP使用recvfrom函數接收數據,當然在數據報套接字綁定了地址和端口后,也可以使用recv函數接收數據。

recv()從內核的接收緩沖區中復制數據到用戶指定的緩沖區,當內核中的數據比指定的緩沖區小時,一般情況下(沒有采用MSG_WAITALL標志)會復制緩沖區中的所有數據到用戶緩沖區,并返回數據的長度。當內核中的數據比指定的緩沖區多時,會將用戶指定的長度的接收緩沖區中的數據復制到用戶指定地址,其余的數據需要下次調用接收函數時再復制,內核在復制用戶指定的數據后,會銷毀已經復制完畢的數據,并進行調整。

send函數:

#include <sys/types.h>#include <sys/socket.h>ssize_t send(int s,const void*buf,size_t len,int flags);

send函數將緩沖區buf中的大小為len的數據,通過套接字文件描述符s按照flasg指定的方式發生出去(其中的含義與recv()中一致),它的返回值是成功發生的字節數。

由于用戶緩沖區buf中的數據通過send發送,不一定能夠全部發送出去,所以要檢查send()返回值。當send()的返回值小于len時,表面緩沖區中仍有部分數據沒有發送成功,這時需要重新發送剩余部分的數據。通常的剩余數據發送方式是對原來的buf中的數據位置進行偏移,偏移的大小為已經發送成功的字節數。

當send()返回-1時,就錯誤了。

函數send()只能用于套接字處于連接狀態的描述符,之前必須用connect()函數或者其他函數進行連接。對于send和write之間的差別是表示發送方式flag,當flag為0時,send()和write()完全一樣的,且send(s,buf,len,flags)和sendto(s,buf,len,flags,NULL,0)是等價的。

readv函數:

#include <sys/uio.h>ssize_t readv(int s,const struct iovec*vector,int count);

read()可以接收多個緩沖區的數據。readv函數從套接字描述符s中讀取count塊的數據放在緩沖區向量vector中。返回值為成功接收到的數據的字節數,當-1時,錯誤發生。

其中的參數vector為一個向量的指針,結構struct iover在文件<sys/uio.h>定義:

1 struct iovec2 {3     void*iov_base;                             // 向量的緩沖區地址4     size_t iov_len;                             // 大小,字節為單位5 }

在調用readv的時候必須指定iovec的iov_len長度,將值放在iov_len中。參數vector指向一塊結構vector的內存,大小count定。如下圖,其中陰影部分是需要設置的。

writev函數:

#include <sys/uio.h>ssize_t writev(int s,const struct iovec*vector,int count);//// 是不是覺得和readv一樣

總結:

下表總結了各個函數的區別、特點:O標記的為具備此種屬性


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宜宾市| 杭锦旗| 筠连县| 沈丘县| 白朗县| 吴江市| 河曲县| 姚安县| 开封市| 改则县| 宁远县| 印江| 永州市| 高要市| 蒲江县| 岳池县| 竹山县| 龙泉市| 伊金霍洛旗| 胶州市| 乌苏市| 页游| 嘉禾县| 寿阳县| 茶陵县| 屏东县| 漳平市| 云阳县| 山东| 五大连池市| 三都| 西乡县| 林芝县| 英山县| 龙海市| 拉萨市| 福泉市| 利川市| 原阳县| 华蓥市| 琼海市|