網路程式設計常用I O函式

2021-09-24 03:34:59 字數 3804 閱讀 8465

read/write

readv/writev

「對資料進行整合傳輪及傳送的函式。」

也就是說,通過writev 函式可以將分散儲存在多個緩衝中的資料一併傳送,通過readv函式可以由多個緩衝分別接收。因此,適當使用這2個函式可以減少i/o函式的呼叫次數。下面先介紹writev 函式。

#include ssize t writev(int filedes, const struct iovec * iov, int iovcnt);

//成功時返回傳送的位元組數,失敗時返回-1 。

#filedes 表示資料傳輸物件的套接字檔案描述符。但該函式並不只限於套接字,因此,可以像read函式一樣向其傳遞檔案或標準輸出描述符。

#iov iovec結構體陣列的位址值,結構體 iovec 中包含待傳送資料的位置和大小資訊。

#iovcnt 向第二個引數傳遞的陣列長度。

合理使用readv & writev 函式哪種情況適合使用readv和writev函式? 實際上,能使用該函式的所有情況都適用。例如, 需要傳輸的資料分別位於不同緩衝(陣列)時,需要多次呼叫write函式。此時可以通過1 次writev函式呼叫替代操作,當然會提高效率。同樣,需要將輸入緩衝中的資料讀入不同位置時,可以不必多次呼叫read函式,而是利用1 次readv函式就能大大提高效率。

即使僅從c語言角度看,減少函式呼叫次數也能相應提高效能。但其更大的意義在於減少資料報個數。假設為了提高效率而在伺服器端明確阻止了nagle演算法。其實writev函式在不採用nagle演算法時更有價值,如圖所示。

上述示例中待傳送的資料分別存在3個不同的地方,此時如果使用write 函式則需要3次函式呼叫。但若為提高速度而關閉了nagl哆垃~. 則極有可能通過3個資料報傳遞資料。反之,若使用writev函式將所有資料一次性寫入輸出緩衝,則很有可能僅通過1個資料報傳輸資料。所以wri tev 函式和readv函式非常有用。

再考慮一種情況: 將不同位置的資料按照傳送順序移動(複製)到l個大陣列,並通過1 次write函式呼叫進行傳輸。這種方式是否與呼叫writev函式的效果相同?當然! 但使用writev函式更為便利。因此,如果遇到writev 函式和readv函式的適用情況,希望各位不要錯過機會。

參考:

recv/send

#include ssize_t recv(int sockfd, void* buf, size_t nbytes, int flags);

//成功時返回接收的位元組數(收到edf 時返回0)' 失敗時返回-1 。

#sockfd 表示資料接收物件的連線的套接字檔案描述符。

#buf 儲存接收資料的緩衝位址值。

#nbytes 可接收的最大位元組數。

#flags 接收資料時指定的可選項資訊。

#include ssize_t send(int sockfd, const void * buf, size_t nbytes, int flags);

//成功時返回傳送的位元組數,失敗時返回-1。

#sockfd 表示與資料傳輸物件的連線的套接字檔案描述符。

#buf 儲存待傳輸資料的緩衝位址值。

#nbytes 待傳輸的位元組數。

#flags 傳輸資料時指定的可選項資訊。

由於不能繫結ip位址,所以只能借助於connect來實現連線和傳送和接收資訊。

參考:

recvmsg/sendmsg

#include ssize_t recvmsg(int socket,      struct msghdr *message,   int   flags);

ssize_t sendmsg (int __fd, const struct msghdr *__message, int __flags);

struct msghdr

;

參考:

sendto/recvfrom

基於udp 的資料i/o函式

#include ssize_t sendto(int sock, void *buff, size_t nbytes, int flags, struct sockaddr *to, socklen_t addrlen);

//成功時返回傳輸的位元組數,失敗時返回-1 。

#sock 用於傳輸資料的udp套接字檔案描述符。

#buff 儲存待傳輸資料的緩衝位址值。

#nbytes 待傳輸的資料長度,以位元組為單位。

#flags 可選項引數,若沒有則傳遞0。

#to 存有目標位址資訊的sockaddr結構體變數的位址值。

#addrlen 傳遞給引數to的位址值結構體變數長度。

#include ssize_t recvfrom(int sock, void *buff, size_t nbytes, int flags, struct sockaddr * from, socklen_t *addrlen);

成功時返回接收的位元組數,失敗時返回-1。

#sock 用於接收資料的udp套接字檔案描述符。

#buff 儲存接收資料的緩衝位址值。

#nbytes 可接收的最大位元組數,故無法超過引數butt所指的緩衝大小。

#flags 可選項引數,若沒有則傳入0 。

#from 存有傳送端位址資訊的sockadd結構體體變數的位址值。

#addrlen 儲存引數from的結構體變數長度的變數位址值。

參考:

函式read()/write()和readv()/writev()可以對所有的檔案描述符使用:recv()/send), recvfrom()/writeto0)和recvmsg/sendmsg只能操作套接字描述符。

函式readv()/writev()和recvmsg()/sendmsg)可以操作多個緩衝區, read()/write()、recv()/send()和recvfrom()/sendto()只能操作單個緩衝區。

函式recv()/send()、recvfrom()/sendto()和recvmsg()/sendmsg()具有可選標誌。

函式recvfrom()/sendto()和recvmsg()/sendmsg()可以選擇對方的ip位址。

函式recvmsg()/sendmsg()有可選擇的控制信心,能進行高階操作。

io函式比較

4 常用網路IO函式

在linux下,一切都是檔案。檔案描述符是核心為了高效管理已經被開啟的檔案所創件的索引。它是乙個非負整數int fd,用於指代被開啟的檔案。所有執行io操作的系統呼叫都是通過檔案描述符來完成的。open creat等低階io函式返回檔案描述符。不採用緩衝區去寫,依賴作業系統功能對檔案讀寫,不設檔案結...

網路程式設計 13 多種IO函式

這兩個函式的最後乙個引數是收發資料時的可選項。可以利用位或運算 同時傳遞多個資訊。用於傳送 帶外資料 緊急訊息。優先處理。傳送例子 接收例子 編譯並執行上面的send和recv send 127.0.0.1 9190 recv 9190 結果顯示 123urgent message 4 567urg...

網路程式設計教程(五)高階I O函式

用於建立檔案描述符的函式,包括pipe dup dup2函式。用於讀寫資料的函式,包括readv writev sendfile mmap munmap splice和tee函式。用於控制i o行為和屬性的函式,包括fcntl函式。一 用於建立檔案描述符的函式 include int pipe in...